dotnet-grpc 工具

可以使用工具添加.proto文件,当然也可以通过直接修改.csproj项目文件来添加。

工具和文件都支持相对路径。

参考链接: https://docs.microsoft.com/zh-cn/aspnet/core/grpc/dotnet-grpc?view=aspnetcore-5.0

当前只介绍导入本地的.proto文件,导入远程地址的文件,请参考上面链接。

安装:

powershell
$ dotnet tool install -g dotnet-grpc

使用:

powershell
$ dotnet grpc add-file [options] <files>...

命令选项:

powershell
$ dotnet grpc add-file -p 指定项目 -s 服务类型 -o 解析导入目录,分号分隔 --access Public或Internal

对比 .csproj

dotnet grpc 命令:

powershell
$ dotnet grpc add-file -p 指定项目 -s Client -o Protos --access Internal

对应 .csproj 文件中的配置:

xml
<ItemGroup> <Protobuf Include="Protos\common.proto" GrpcServices="Client" AdditionalImportDirs="Protos" Access="Internal" Link="Protos\common.proto"/> </ItemGroup>
  • -p:对应 .csproj文件位置。
  • -s:对应 GrpcServices,支持的值NoneDefaultBothServerClient
  • -o:对应 AdditionalImportDirs,用 ; 号分隔多个目录。
  • --access:对应 Acess,支持的值 Public(默认),Internal
  • Link:是使用命令时自动生成,表示链接到一个文件而不是当前项目中存在这个文件,相当于桌面快捷方式。

示例

项目结构

txt
- solution - project-server ... 其他 - protos //链接 common.proto //链接 xxx.proto //链接 - project-client ... 其他 - protos //链接 common.proto //链接 xxx.proto //链接 - protos-shared ... 其他 - protos common.proto xxx.proto

protos-shared

common.proto

protobuf
syntax = "proto3"; option csharp_namespace = "Protos"; package protos.shared; // import public // - 同时导出这个文件中的类型,其他文件导入这个文件时,自动导入这些类型 import public "google/protobuf/empty.proto"; import public "google/protobuf/wrappers.proto"; import public "google/protobuf/timestamp.proto"; message IdStringRequest{ string id = 1; }

xxx.proto

protobuf
syntax = "proto3"; option csharp_namespace = "Protos"; package protos.shared; // 文件路径是从当前项目根目录开始的路径。 import "protos/common.proto"; message IdStringRequest{ string id = 1; } service Xxx { rpc GetStarDetail(IdStringRequest) returns (google.protobuf.Empty); }

protos-shared.csproj

xml
<ItemGroup> <Protobuf Include="protos\common.proto" /> <Protobuf Include="protos\xxx.proto"/> </ItemGroup>

project-server.csproj

xml
<ItemGroup> <Protobuf Include="..\protos-shared\protos\common.proto" GrpcServices="Server" Link="protos\common.proto"/> <Protobuf Include="..\protos-shared\protos\xxx.proto" GrpcServices="Server" Link="protos\xxx.proto" AdditionalImportDirs="..\protos-shared"/> </ItemGroup>

project-client.csproj

xml
<ItemGroup> <Protobuf Include="..\protos-shared\protos\common.proto" GrpcServices="Client" Link="protos\common.proto"/> <Protobuf Include="..\protos-shared\protos\xxx.proto" GrpcServices="Client" Link="protos\xxx.proto" AdditionalImportDirs="..\protos-shared"/> </ItemGroup>

其他说明

在上面的示例中,在 xxx.proto 中使用 import "protos/common.proto" 来导入 common.proto 文件。

如果想使用 import "common.proto 这种形式,只需要在 .csproj 文件中的 Protobuf 元素的对应添加 AdditionalImportDirs="protos",但是这种形式在使用 GrpcReflection(如 grpcui) 时,会报找不到 common.proto 文件的错误,似乎它搜索 .proto文件只是从项目根目录搜索,而不是读取的.csproj文件配置。这里不再探究这个问题。上面的示例形式已经够用了。

另外请注意 ProtobufAdditionalImportDirs.proto 文件中的 import 路径的对应关系,import的路径必须是 AdditionalImportDirs 指定的下一级,而 AdditionalImportDirs 的默认路径是项目的根目录,它可以配置__多个目录__,只需用 ; 号分隔各个目录。