Jos*_*hlo 3 c# protocol-buffers protobuf-net
我有几个包含不同 protobuf 文件的合同项目,但是某些消息类型具有相同的消息类型,例如
message user
{
Address address = 1
}
message Address
{
....
}
Run Code Online (Sandbox Code Playgroud)
我现在创建了一个共享项目并向其中添加了一个 Address.proto 文件,其中仅包含
syntax = "proto3"
option csharp_namespace = "shared.protos"
package AddressPackage
message Address {....}
Run Code Online (Sandbox Code Playgroud)
我的问题是弄清楚如何将其导入到我不同合同项目中的原型中。我已添加共享项目作为参考,但我从那里尝试的所有其他内容都导致错误。
我知道我需要使用import只是还没有弄清楚如何写字符串。
更新
我正在使用 gRPC.tools nuget 并且所有 .proto 文件都设置为 protobuf 编译器
文件结构如下
用户合同项目
两个项目都在它自己的文件夹中,并且这些文件夹彼此相邻。
在它说的共享项目中
<ItemGroup>
<None Remove="Protos\Address.proto" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos\Address.proto">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Protobuf>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
并在 user.contract 中说
<ItemGroup>
<None Remove="Protos\User.proto" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos\User.proto" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
提前致谢。
您可以通过将ProtoRoot属性添加到文件中的<Protobuf />部分来实现.csproj。
假设您.proto在项目 A 中有一个文件:
syntax = "proto3";
option csharp_namespace = "Project.A";
import "ProjectB/<path>/Engine.proto"
message Car {
Engine engine = 1;
...
}
Run Code Online (Sandbox Code Playgroud)
在项目 B 中,您有:
syntax = "proto3";
option csharp_namespace = "Project.B";
message Engine {
...
}
Run Code Online (Sandbox Code Playgroud)
如您所见,car.proto我们.proto在另一个项目中对文件使用了导入语句。为了成功地导入此文件,我们需要添加ProtoRoot到<Protobuf />该节.csproj的项目中的文件:
<ItemGroup>
<Protobuf Include="ProjectA/<path>/car.proto" Link="<path>/car.proto" ProtoRoot=".." />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
<path>相当于 .NET 项目中的文件夹结构。ProtoRoot需要设置为文件中的导入声明.proto正在查找文件的目录。在这种情况下,它是包含两个子文件夹的父文件夹,其中包含项目 A 和项目 B。
更多有趣的东西可以在这里找到:https : //chromium.googlesource.com/external/github.com/grpc/grpc/+/HEAD/src/csharp/BUILD-INTEGRATION.md
这比我预见的要复杂得多,因为大量的“移动部件”加上文档在某种程度上已经过时了,并且在撰写本文时,某些属性的行为似乎与上面的帖子不同。
\n基本上在上面的汽车示例中,使用 Visual Studio 2022 你应该得到这个\n
为了实现这一点,ProjA 需要做大量的工作,有趣的部分是
\n<ItemGroup>\n <ProjectReference Include="../ProjB/ProjB.csproj" />\n</ItemGroup>\n\n<ItemGroup> \n <Protobuf Include="..\\ProjB\\Protos\\engine.proto" GrpcServices="None" ProtoCompile="False">\n <Link>ProjB\\Protos\\engine.proto</Link> \n </Protobuf> \n <Protobuf Include="../ProjA/Protos/car.proto" Link="Protos/car.Proto" GrpcServices="None" ProtoRoot=".." />\n</ItemGroup>\nRun Code Online (Sandbox Code Playgroud)\n请注意,正如 Yury Yatskov 和 Ivan Ivkovi\xc4\x87 所说,重要的部分是设置,ProtoRoot=".."但 ProtoRoot 中指定的路径必须是 Include 属性中路径的前缀。\n注意:
ProtoRoot与 .csproj 文件相关Import与 .csproj 文件相关,但需要有ProtoRoot前缀,所以基本上上升一级,然后再次进入 ProjA 内部这样,include语句car.proto将能够从指定的路径开始ProtoRoot搜索要包含的 .proto 文件
** ProjA/Protos/car.proto
\nsyntax = "proto3";\n\nimport "ProjB/Protos/Engine.proto";\n\noption csharp_namespace = "ProjA";\n\npackage ProjA;\n\nmessage Car{\n ProjB.Engine engine = 1;\n string licensePlate = 2;\n}\nRun Code Online (Sandbox Code Playgroud)\n** ProjB/Protos/engine.proto
\nsyntax = "proto3";\noption csharp_namespace = "ProjB";\n\npackage ProjB;\n\nmessage Engine{\n string name = 1;\n}\nRun Code Online (Sandbox Code Playgroud)\n再次注意,当然您需要使用其包来引用引擎消息,以便ProjB.Engine
最后,这允许将 ProjB 作为 ProjA 的正常参考包含在内
\n\n但要注意设置Compile Protobuf为“否”(如您在上面报告的 .csproj 中看到的),否则会出现类名冲突,因为两个项目将重新定义相同的“Engine”类。
grpc stub classes属性在这里似乎没有发挥很大的作用,我认为如果 .proto 包含服务定义会更有趣。
小智 6
在您的项目中,使用 Include 和 ProtoRoot 指定 Protobuf,其中应包含带有原型文件的共享项目的路径,例如
<ItemGroup>
<Protobuf Include="..\NameSharedProject\Protos\address.proto" ProtoRoot="..\NameSharedProject" GrpcServices="Server" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
然后,在构建每个项目后,您将在文件夹“\obj\Debug\net5.0\Protos”中创建类文件。
| 归档时间: |
|
| 查看次数: |
7615 次 |
| 最近记录: |