grpc-dotnet icon indicating copy to clipboard operation
grpc-dotnet copied to clipboard

MapGrpcService non static alternative

Open jakubbukaj opened this issue 2 years ago • 3 comments

Hello, I am migrating server from Grpc.Core to Grpc.AspNetCore.Server. In Grpc.Core I was using:

Grpc.Core.Server server = new Grpc.Core.Server()
{
   Services = { _instanceOfMyServiceImplementation.GetServiceDefinition() },
   Ports =
   {
        new ServerPort("0.0.0.0", 5555, Grpc.Core.ServerCredentials.Insecure)
   }
};

In my service was following registration method and handler as:

public ServerServiceDefinition GetServiceDefinition()
        {
            return ServerServiceDefinition.CreateBuilder()
                .AddMethod(_duplexCommunicationMethod, DuplexCommunication).Build();
        }

for binding incommning calls to specific nonstatic processing method and handler.

I am now migrating to Grpc.AspNetCore.Server. I would like to avoid static classes, methods if possible. I was able to create my service as singleton. But I am not able to register processing _duplexCommunicationMethod method and handler from my instanced service implementation. I would need endpoints.MapGrpcService alternative mapping from specific instance not from Type and using static methods. Something like this:

var instanceOfMyServiceImplementation = <Got from different DI container>
var builder = Host.CreateDefaultBuilder().ConfigureWebHostDefaults(webBuilder =>
{
    webBuilder.UseKestrel();
    webBuilder.ConfigureServices(services =>
    {
        services.AddSingleton(communicationService);
        services.AddGrpc();
    });

    webBuilder.Configure((context, app) =>
    {
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.BindGrpcService(instanceOfMyServiceImplementation.BindService());
        });
    });
});

with BindService like this:

public ServiceBinderBase BindService ()
{
    ServiceBinderBase sbb = new ServiceBinderBase();
    sbb.AddMethod(_duplexCommunicationMethod, DuplexCommunication);
    return sbb;
}

Is it possible? Thanks

jakubbukaj avatar Mar 05 '22 06:03 jakubbukaj

This isn't easily supported today.

This PR - https://github.com/grpc/grpc-dotnet/pull/1617 - has an example of hacking a custom method by using IServiceMethodProvider.

Check out GenericServiceMethodProvider.cs and ServerRunner.cs.

JamesNK avatar Mar 09 '22 23:03 JamesNK

Thank you for pointing me to right direction.

jakubbukaj avatar Mar 11 '22 12:03 jakubbukaj

I had a similiar issue here: https://github.com/grpc/grpc-dotnet/issues/1690

I used reflection to call the MapGrpcService with a runtime type. Sure this is not the best solution and reflection is slow, but the performance can be ignored, as this is a one time startup operation. At least for me it works great.

Soon5 avatar Apr 29 '22 17:04 Soon5