Easily sharing gRPC protos among .NET projects


Easily sharing gRPC protos among .NET projects

As developers, we usually have the drive to avoid duplicating code as much as we can, since we know the maintenance hell that it can cause. That’s why the DRY principle was created. Sharing gRPC protos is definitely something that can be done, although for a beginner it might not be crystal clear how to achieve it.

TL;DR

A sample code can be found in this repository.

Basic structure

Creating a gRPC service

Let’s start by creating our gRPC service by using the ASP.NET Core gRPC Service template. We’ll name it “Service” and use the following settings:

We’ll leave it as it is for now, and continue creating the other pieces of our puzzle.

Creating the client project

For the client, we are going to create a standard console application. Once created, add the package references below to it. They will be used for creating our gRPC Greeter client and finding .proto files. The Grpc.Tools package is marked with PrivateAssets=”all” as it is not required during runtime.

  <ItemGroup>
    <PackageReference Include="Google.Protobuf" Version="3.25.3" />
    <PackageReference Include="Grpc.Net.Client" Version="2.61.0" />
    <PackageReference Include="Grpc.Tools" Version="2.62.0" PrivateAssets="all"/>
  </ItemGroup>

We’ll also leave this project for now, as we need our protos project to finish it. A word of caution: when creating the projects, ensure that they are all under the same folder, as the image below demonstrates. We’ll get to the reason for that soon enough.

Creating the shared protos project

Finally, we are going to create a shared project that stores our protos. This project is going to be a class library, and we’ll be calling it “Protos”. Again, check that the project’s folder location is in the right place.

Now that it has been created, let’s move the generated greet.proto file in our server project to this one. Cut and copy the file to the Protos project root. It should be looking like this:

Now we are going to make a small change in our .proto file. We are going to change the value of option csharp_namespace to “Protos”, since the file is not in the server project anymore.

So with that, we have our shared project up and ready to be used. Time to reference it in our other projects. Open your Client.csproj and add the following lines:

<ItemGroup>
  <Protobuf Include="..\Protos\greet.proto" GrpcServices="Client" Link="Protos\greet.proto" />
</ItemGroup>

And in your Server.csproj, replace the existing Protobuf reference with this one:

<ItemGroup>
  <Protobuf Include="..\Protos\greet.proto" GrpcServices="Server" Link="Protos\greet.proto" />
</ItemGroup>

The “Include” attribute tells our projects where to look for the files. That’s why the folder structure is important in this scenario. We also have the “GrpcServices” attribute, which limits C# asset generation. Lastly, the “Link” attribute dictates where the .proto file will show up in our solution. If you rebuild your solution now, you should be seeing the protos files in all solutions. And you are done!

Testing

In case you want to test it, you can update the contents of your Program.cs class to create a client and send it a request. You can use the sample code below, just be sure that you are using the same port that your server is using. This information can be found in your Server/Properties/launchSettings.json file, in the “applicationUrl” property. And be sure to run your server, of course.