Friday, September 25, 2020

gRPC and .Net Core

 When Microsoft started pushing .Net Core they announced they would not be supporting WCF. This caused quite a stir in the Microsoft community so Microsoft relented and added WCF support that became available with the Visual Studio 2017 version 15.5 release. 

Nevertheless, Microsoft is still touting the advantages of gRPC rather than WCF for new .Net Core development. Reading through the gRPC documentation I am unhappy at the poor support for Guid, Decimal, DateTime, and TimeSpan types. These are all types we use a lot. If Google can have their own custom Protobuf types, why can't Microsoft?

Visual Studio has a project template of gRPC Service which, like the WCF Service Application project template, contains some example code. Let's see what's in here, and how we would write a client to consume their example service. I'm using Visual Studio 2019 Enterprise version 16.7.4.

Start a new project using the gRPC Service template. Call it HelloService.

Take all the defaults. Once the project has been created you will see a HelloService tab. Close it. You can build and run the service immediately. It is self hosting. There is a console program in program.cs that configures it and launches it. There are other hosting options that I'm not going to get into in this blog entry. You can read the Microsoft introduction to gRPC for WCF developers to understand how it works. Pay special attention to the proto file which replaces the interface that WCF users.

If you run the service now (which you need to) you will see a console like this. The service must be running for the client to work.



To write the host, start a new copy of Visual Studio and create a new C# console app called HelloClient.


Accessing the gRPC service has the same types of steps as accessing a WCF client. We start by creating a reference to it in the project, then in code we create a channel and execute a method.

Creating the reference.

Right-click on dependencies and select Add Connected Service. This displays a page that allows us to add a Service Reference. Click the Add button in the Service References section.



Now select gRPC and click [Next]. I find it easiest to browse to the HelloService's proto file so click on [Browse] and browse to the proto file.


Back at the 'Add new gRPC service reference" window, click [Finish], then click [Close]. The HelloClient tab should now look like this.


Code Time!

Start by adding a using for Grpc.Net.Client and HelloService. Then add code to create a channel and an instance of the Greeter service. Program.cs looks like this.

using System;
using Grpc.Net.Client;
using HelloService;
 
namespace HelloClient
{
    class Program
    {
        static void Main(string[] args)
        {
            GrpcChannel channel = GrpcChannel.ForAddress("https://localhost:5001");
            Greeter.GreeterClient client = new Greeter.GreeterClient(channel);
        }
    }
}

Now we create and populate the request and the reply. Append this code.

            HelloRequest request = new HelloRequest() { Name = "Terry" };
            HelloReply reply = client.SayHello(request);

Lastly we pull the data out of the reply.

            Console.WriteLine(reply.Message);

At this point Program.cs should look like this.

using System;
using Grpc.Net.Client;
using HelloService;
 
namespace HelloClient
{
    class Program
    {
        static void Main(string[] args)
        {
            GrpcChannel channel = GrpcChannel.ForAddress("https://localhost:5001");
            Greeter.GreeterClient client = new Greeter.GreeterClient(channel);
            HelloRequest request = new HelloRequest() { Name = "Terry" };
            HelloReply reply = client.SayHello(request);
            Console.WriteLine(reply.Message);
        }
    }
}

When you run HelloClient you will see a console window like this.


As you can see, the consumption of the gRPC service is quite similar to the consumption of a WCF service.

PS. A few days after I wrote this blog entry I found this tutorial on microsoft.com which is almost identical.


No comments:

Post a Comment