VS 扩展开发:Grpc Proto To NuGet Package

一直以来我们使用 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 并发布到私有仓库。

实现方案

  1. 创建 gRPC 接口生成的项目模板,关于 .NET 项目模板创建可参考文章:ASP.NET 自定义项目模板

  2. 创建 VS 扩展插件 Grpc Proto To NuGet Package

  3. 右键选中 proto 接口定义文件所在的文件夹(所有 proto 文件中定义的 package 名暂必须一致,公共 proto 文件暂只能放在根目录的 common 文件夹下),在右键菜单中点击 Grpc Proto To NuGet Package,首次需要配置私有 NuGet 仓库源地址和 API Key,然后根据 package 名自动创建基于项目模板的临时项目,同时会把当前选中文件夹内的 proto 文件复制到临时项目中,执行代码生成命令;

  4. 介于 gRPC 客户端调用需要对 channel 进行复用,所以同时会基于 T4 模板自动生成复用 channel 的 client 代码,调用时就不用再考虑 channel 复用问题 ;

  5. 最终通过 dotnet builddotnet nuget push 自动将生成的 NuGet Package 推送到私有仓库;

  6. 删除临时项目。

使用方法

  1. 下载最新 GrpcProtoToNuGetPackageTemplate.zip ASP.NET 的项目模板;

  2. 解压 GrpcProtoToNuGetPackageTemplate.zip,在安装之前最好对以下文件进行必要的修改,主要是团队相关信息:

    Content/.template.config/template.json: author
    Grpc.Proto.To.NuGet.Package.nuspec: authors
    GrpcProtoToNuGetPackage.csproj: Authors、Company、RepositoryUrl,其他看情况修改如:TargetFrameworks .

    模板结构

  3. 执行 nuget pack Grpc.Proto.To.NuGet.Package.nuspecnuget 如果不存在,需要下载并将 nuget.exe 添加到环境变量) 生成 Grpc.Proto.To.NuGet.Package.1.0.0.nupkg

  4. 执行 dotnet new -i Grpc.Proto.To.NuGet.Package.1.0.0.nupkg 进行模板安装;

  5. 安装成功后,可通过 dotnet new -u 进行查看现有的项目模板,如下:Grpc.Proto.To.NuGet.Package 即安装的项目模板,如果需要卸载,执行 dotnet new -u Grpc.Proto.To.NuGet.Package

    Grpc.Proto.To.NuGet.Package.Template

  6. 下载最新版 GrpcProtoToNuGetPackage.vsix,在关闭所有 VS 窗口下安装此插件;

  7. 安装成功后,VS 中打开含 proto 接口定义文件的项目(我们目前是将所有 gRPC 服务按文件夹存放到一个公共项目中,统一维护);

  8. protos 文件夹右键选择 Grpc Proto To NuGet Package,如下:

    Grpc.Proto.To.NuGet.Package

  9. 点击后会弹出配置窗口,设置 NuGet Package 要推送到的 源地址APIKey(只需首次设置)

    可在 https://www.nuget.org 官网注册账号,并创建 API Key 进行测试,不过这样是推送到公共平台上

    NuGet Package Setting

  10. 设置 NuGet Package 包名和版本(包名默认是 proto 文件定义的 package 名,版本号默认是当前最大版本的 revision 位加 1),也可完全自定义

    执行过程中使用的资源文件会暂存到 C:\TempGrpcNuGet 目录下。首次会创建 repository.json 保存 NuGet 仓库的配置信息,接下来每次会根据包名创建一个临时项目用于生成对应 NuGet Package,如果有问题,一般是因不符合规范导致编译不通过,这时候可在临时项目中通过 dotnet build 进行编译或通过 VS 添加现有项目查看具体问题。

  11. 执行,注意执行结果内的输出日志,确保推送到远端仓库 OK

    Published Packages

  12. NuGet Package 安装与使用

    Install MyHelloworld

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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 步:

  1. 安装 GrpcProtoToNuGetPackageTemplate 项目模板;
  2. 安装 Grpc Proto To NuGet Package VS 插件;
  3. 配置私有 NuGet 仓库;
如果对你有帮助就好