一直以来我们使用 gRPC 来进行微服务开发,对 gRPC
有过了解应该清楚它依赖 proto
接口定义文件来实现的,在进行服务调用之前,需要先通过 proto
文件来生成当前服务使用语言的代码,然后就可以实现调用本地方法一样调用远程服务。(.NET Core 3.0 开始已支持不用手动生成代码就可以调用方法,但在多语言的微服务开发中,proto
文件的维护还是比较倾向我们目前的方式)
在 .NET 开发中,我们之前的方式还是根据 proto
文件手动生成代码,接着生成 NuGet Package ,然后推送到自己的私有 NuGet 仓库,最后在服务内进行 NuGet Package 安装来引用,这样不至于需要依赖此服务的服务每次都 copy 代码,目的是在服务引用上简化一些步骤。
但问题又来了,要最终实现推送到自己的私有 NuGet 仓库的步骤实在太多,这样依然效率低下,最后我们决定还是自己开发一个 VS 插件 Grpc Proto To NuGet Package ,功能就是一键生成 NuGet Package 并发布到私有仓库。
实现方案
创建
gRPC
接口生成的项目模板,关于 .NET 项目模板创建可参考文章:ASP.NET 自定义项目模板 ;创建 VS 扩展插件
Grpc Proto To NuGet Package
;右键选中
proto
接口定义文件所在的文件夹(所有proto
文件中定义的package
名暂必须一致,公共proto
文件暂只能放在根目录的common
文件夹下),在右键菜单中点击Grpc Proto To NuGet Package
,首次需要配置私有 NuGet 仓库源地址和 API Key,然后根据package
名自动创建基于项目模板的临时项目,同时会把当前选中文件夹内的proto
文件复制到临时项目中,执行代码生成命令;介于
gRPC
客户端调用需要对 channel 进行复用,所以同时会基于 T4 模板自动生成复用 channel 的 client 代码,调用时就不用再考虑 channel 复用问题 ;最终通过
dotnet build
和dotnet nuget push
自动将生成的 NuGet Package 推送到私有仓库;删除临时项目。
使用方法
下载最新 GrpcProtoToNuGetPackageTemplate.zip ASP.NET 的项目模板;
-
解压
GrpcProtoToNuGetPackageTemplate.zip
,在安装之前最好对以下文件进行必要的修改,主要是团队相关信息:Content/.template.config/template.json
: author
Grpc.Proto.To.NuGet.Package.nuspec
: authors
GrpcProtoToNuGetPackage.csproj
: Authors、Company、RepositoryUrl,其他看情况修改如:TargetFrameworks
. 执行
nuget pack Grpc.Proto.To.NuGet.Package.nuspec
(nuget 如果不存在,需要下载并将 nuget.exe 添加到环境变量) 生成Grpc.Proto.To.NuGet.Package.1.0.0.nupkg
;执行
dotnet new -i Grpc.Proto.To.NuGet.Package.1.0.0.nupkg
进行模板安装;-
安装成功后,可通过
dotnet new -u
进行查看现有的项目模板,如下:Grpc.Proto.To.NuGet.Package
即安装的项目模板,如果需要卸载,执行dotnet new -u Grpc.Proto.To.NuGet.Package
下载最新版 GrpcProtoToNuGetPackage.vsix,在关闭所有 VS 窗口下安装此插件;
安装成功后,VS 中打开含
proto
接口定义文件的项目(我们目前是将所有 gRPC 服务按文件夹存放到一个公共项目中,统一维护);-
在
protos
文件夹右键选择Grpc Proto To NuGet Package
,如下: -
点击后会弹出配置窗口,设置 NuGet Package 要推送到的
源地址
和APIKey
(只需首次设置)可在 https://www.nuget.org 官网注册账号,并创建 API Key 进行测试,不过这样是推送到公共平台上
-
设置 NuGet Package 包名和版本(包名默认是
proto
文件定义的package
名,版本号默认是当前最大版本的 revision 位加 1),也可完全自定义执行过程中使用的资源文件会暂存到
C:\TempGrpcNuGet
目录下。首次会创建repository.json
保存 NuGet 仓库的配置信息,接下来每次会根据包名创建一个临时项目用于生成对应 NuGet Package,如果有问题,一般是因不符合规范导致编译不通过,这时候可在临时项目中通过dotnet build
进行编译或通过 VS 添加现有项目查看具体问题。 -
执行,注意执行结果内的输出日志,确保推送到远端仓库 OK
-
NuGet Package 安装与使用
static void Main(string[] args) { // client 集合 var clientContainer = new ClientContainer("127.0.0.1:1234"); // GreeterClient,如果有多个 Client,也是直接从 clientContainer 中获取 var greeterClient = clientContainer.GreeterClient; var response = greeterClient.SayHello(new HelloRequest { Name = "BeckJin" }); Console.WriteLine(response.Message); }
总结
以上主要是实现方案及使用方法的具体说明,实际使用 Grpc Proto To NuGet Package
只需如下 3 步:
- 安装
GrpcProtoToNuGetPackageTemplate
项目模板; - 安装
Grpc Proto To NuGet Package
VS 插件; - 配置私有 NuGet 仓库;