IndependentReserve.Grpc.Tools 1.9.116

There is a newer version of this package available.
See the version list below for details.
dotnet add package IndependentReserve.Grpc.Tools --version 1.9.116                
NuGet\Install-Package IndependentReserve.Grpc.Tools -Version 1.9.116                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="IndependentReserve.Grpc.Tools" Version="1.9.116">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add IndependentReserve.Grpc.Tools --version 1.9.116                
#r "nuget: IndependentReserve.Grpc.Tools, 1.9.116"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install IndependentReserve.Grpc.Tools as a Cake Addin
#addin nuget:?package=IndependentReserve.Grpc.Tools&version=1.9.116

// Install IndependentReserve.Grpc.Tools as a Cake Tool
#tool nuget:?package=IndependentReserve.Grpc.Tools&version=1.9.116                

IndependentReserve.Grpc.Tools

Purpose

This package contains MSBuild tasks and targets for automatic generation of gRPC/Protobuf code from plain C# interface(s).

How it works

When this package is referenced by a project it adds itself into compilation pipeline in the following way:
For every depended project which is marked by GenerateGrpc attribute it loads all eligible C# interfaces and for every such source interface it generates the following code:

  • a set of *.proto files defining gRPC service and messages plus the hierarchy of all DTO classes referenced by the source interface;
  • a set of C# partial classes which provide implicit conversion operators for Protobuf ↔ DTO conversion for every generated *.proto file;
  • gRPC service implementation which depends on source interface and internally calls this interface for corresponding interface method implementation;
  • gRPC client class which implements the source interface by calling gRPC server via gRPC.

How to use it

To use this tool first you need to reference this NuGet package in your project via PackageReference, e.g.:

<ItemGroup>
  <PackageReference Include="IndependentReserve.Grpc.Tools" Version="1.9.*" />
</ItemGroup>

gRPC/Protobuf code generation

To generate all required gRPC/Protobuf code in a project you need to point it to a separate project which contains interface (or interfaces) which you want to generate gRPC/Protobuf types for. To do that simply add GenerateGrpc="true" attribute to ProjectReference element of the relevant source project, e.g.:

<ItemGroup>
  <ProjectReference Include="..\Service.Interface.csproj" GenerateGrpc="true" />
</ItemGroup>

By default the tool searches for all C# interfaces with the name matching Service$ regular expression (e.g. ISomeService) and generates all required gRPC-related code for every found interface.
To use a different pattern for interface search specify a custom regular expression (.NET flavor) via GrpcServicePattern attribute, e.g.:

<ItemGroup>
  <ProjectReference Include="..\Service.Interface.csproj" >
    <GenerateGrpc>true</GenerateGrpc>
    <GrpcServicePattern>I[^.]*ServiceInterface$</GrpcServicePattern>
  </ProjectReference>
</ItemGroup>  

Note: the source interfaces must be in a separate dependent project because the tool uses reflection to load and process source interfaces during the build.

All generated files are placed in obj/[Configuration]/[TargetFramework]/Grpc root folder and are automatically included into project's build.
All *.proto files are placed in Protos subfolder:

  • [service-name].proto file: gRPC service definition file which defines all methods mirroring source interface methods;
  • [service-name]Messages.proto file: this file contains all *Request and *Response messages referenced from [service-name].proto file;
  • [class-name].proto files: a hierarchy of messages which are referenced (directly or indirectly) by messages from [service-name]Messages.proto.

All *.cs files are placed in Partials subfolder:

  • [service-name]GrpcService.cs: gRPC service class:
    This class depends on the source interface and it is expected that the implementation of this interface passed to gRPC service class constructor (e.g. via dependency injection) contains the internal implementation of the service logic;
  • [service-name]GrpcClient.cs: gRPC client implementation:
    This class implements source interface by calling the service via gRPC (using internal gRPC client class in turn generated by Grpc.Tools). For each method from source interface both synchronous and asynchronous methods are generated.
  • [class-name].cs files: a set of partial C# classes which add implicit conversion operators (Protobuf ↔ DTO) to generated by Grpc.Tools C# classes.
    There is one to one correspondence between this set and [class-name].proto files set.

Among the above set of files normally only C# code is relevant to the user of this package. The Protobuf code can be considered internal. In practice a developer only needs to know about two classes:

  • gRPC service: to host the service in ASP.NET;
  • gRPC client: to call the service.

Both classes depend/implement the source interface while all conversion to/from Protobuf messages is hidden from a developer (and internally implemented using AutoMapper framework).

Example of generated C# code

If we pass the following source interface to the tool:

public interface ITestService
{
    int Plus(int a, int b);
}

it will generate the following gRPC service class:

public partial class TestServiceGrpcService : TestServiceBase
{
    private readonly ILogger<TestServiceGrpcService> _logger;
    private readonly ITestService _testService;

    public TestServiceGrpcService(
        ILogger<TestServiceGrpcService> logger,
        ITestService testService)
    {
        _logger = logger;
        _testService = testService;
    }

    public override async Task<PlusResponse> Plus(PlusRequest request, ServerCallContext context)
    {
        var args = MapperTo<ValueTuple<System.Int32, System.Int32>>.MapFrom(new { Item1 = request.A, Item2 = request.B });
        var result = _testService.Plus(args.Item1, args.Item2);
        return MapperTo<PlusResponse>.MapFrom(new { Result = result });
    }
}

along with the following gRPC client class:

public partial class TestServiceGrpcClient : GrpcClient, ITestService
{
    private readonly Lazy<TestServiceClient> _client;

    public TestServiceGrpcClient(IGrpcServiceConfiguration config, bool useGrpcWeb = true)
        : base(config, useGrpcWeb)
    {
        var invoker = Channel.CreateCallInvoker();
        SetupCallInvoker(ref invoker);
        _client = new(() => new(invoker));
    }

    partial void SetupCallInvoker(ref CallInvoker invoker);

    private TestServiceClient Client => _client.Value;

    public System.Int32 Plus(System.Int32 a, System.Int32 b)
    {
        var response = Client.Plus(MapperTo<PlusRequest>.MapFrom(new { A = a, B = b }));
        return MapperTo<Wrapper<System.Int32>>.MapFrom(response).Result;
    }

    public async Task<System.Int32> PlusAsync(System.Int32 a, System.Int32 b)
    {
        var response = await Client.PlusAsync(MapperTo<PlusRequest>.MapFrom(new { A = a, B = b }));
        return MapperTo<Wrapper<System.Int32>>.MapFrom(response).Result;
    }
}

DTO ↔ Protobuf conversion code test generation

This tool can also generate unit tests for DTO → gRPC → byte[] → gRPC → DTO (round-trip) conversion/serialization path which check that after conversion/serialization the source DTO content is matched by the resulting DTO content.
To add test generation step to a project add GenerateGrpcTests="true" attribute to the ProjectReference to the source interface project, e.g.:

<ItemGroup>
  <ProjectReference Include="..\Service.Interface.csproj" GenerateGrpcTests="true" />
</ItemGroup>

The tool then generates unit tests for every DTO referenced by the source interface. It uses xUnit since this test framework allows test input being provided by an external class via ClassData attribute. Every test is run against generated test data (random DTO content). By default it generates 1000 random DTO instances in every test. This limit can be controlled by setting Arbitrary.TestCount property, e.g.:

  public partial class ConversionTests
  {
      static ConversionTests()
      {
          Arbitrary.TestCount = 10000;
      }
  }

Note: GenerateGrpcTests="true" does not generate source Protobuf code (only tests) since normally unit tests are placed in a separate project which references a project which contains generated (via GenerateGrpc="true") Protobuf code. If you require both code and the tests to be generated in the same project add both GenerateGrpc and GenerateGrpcTests attributes to relevant ProjectReference.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
4.3.253 3,183 8/13/2024
4.2.221 141 7/11/2024
4.2.219 5,506 7/6/2024
4.1.215 17,461 12/15/2023
4.1.210 1,096 11/30/2023
4.0.201 957 11/21/2023
4.0.194 887 11/17/2023
4.0.189 2,976 11/9/2023
4.0.186 786 11/8/2023
4.0.185 815 11/8/2023
3.2.149 2,817 8/15/2023
3.2.146 907 8/11/2023
3.1.145 5,883 4/28/2023
3.1.143 1,217 4/4/2023
3.1.140 1,079 3/29/2023
3.1.138 1,233 3/29/2023
3.1.136 1,310 3/21/2023
3.1.134 1,246 3/21/2023
3.1.132 1,243 3/19/2023
3.1.130 1,124 3/16/2023
2.3.124 1,113 3/13/2023
2.2.119 1,400 3/8/2023
2.2.115 1,876 3/5/2023
2.2.114 1,286 3/5/2023
2.1.108 1,267 3/3/2023
1.9.116 1,256 3/5/2023
1.9.106 1,473 3/3/2023
1.9.104 1,369 3/2/2023
1.8.94 1,490 2/27/2023
1.7.88 1,230 2/27/2023
1.7.86 1,067 2/27/2023
1.6.81 1,895 2/2/2023
1.5.77 1,490 1/26/2023
1.4.69 1,595 1/9/2023
1.4.61 1,460 1/3/2023
1.3.52 1,984 12/16/2022
1.3.48 1,370 12/15/2022
1.2.42 1,889 12/14/2022
1.2.36 1,577 11/29/2022
1.2.33 1,699 11/28/2022