ServiceModel.Grpc

Code-first for gRPC

View on GitHub

ServiceModel.Grpc service and operation bindings

Interface methods are a list of gRPC operations.

[ServiceContract]
public interface IStandardCalculator
{
    [OperationContract]
    int Sum(int x, int y);
}

[ServiceContract]
public interface IScientificCalculator
{
    [OperationContract]
    int Multiply(int x, int y);
}

hosting on the server-side

In the following example on a server start-up there will be 2 gRPC services available IStandardCalculator and IScientificCalculator. IDisposable is ignored as it is not a service contract.

internal sealed class CalculatorService : IStandardCalculator, IScientificCalculator, IDisposable
{
    // POST /IStandardCalculator/Sum
    public int Sum(int x, int y) { /*...*/ }

    // POST /IScientificCalculator/Multiply
    public int Multiply(int x, int y) { /*...*/ }
}

var builder = WebApplication.CreateBuilder();

// enable ServiceModel.Grpc
builder.Services.AddServiceModelGrpc();

var app = builder.Build();

// bind CalculatorService
app.MapGrpcService<CalculatorService>();

call from the client-side

static readonly IClientFactory MyDefaultClientFactory = new ClientFactory(...);

static void Call()
{
    ChannelBase channel = ... // initialize channel

    // POST /IStandardCalculator/Sum
    MyDefaultClientFactory.CreateClient<IStandardCalculator>(channel).Sum(...);

    // POST /IScientificCalculator/Multiply
    MyDefaultClientFactory.CreateClient<IScientificCalculator>(channel).Multiply(...);
}

Contract inheritance

Inheritance of interfaces, defined as ServiceContract, does not affect operation bindings.

[ServiceContract]
public interface ICalculator
{
    [OperationContract]
    int Sum(int x, int y);
}

[ServiceContract]
public interface IScientificCalculator : ICalculator
{
    [OperationContract]
    int Multiply(int x, int y);
}

internal sealed class ScientificCalculator : IScientificCalculator
{
    // POST /ICalculator/Sum
    public int Sum(int x, int y) { /*...*/ }

    // POST /IScientificCalculator/Multiply
    public int Multiply(int x, int y) { /*...*/ }
}

Interface inheritance

If an interface is not marked as ServiceContract, the service name for each defined operation comes from the top ServiceContract interface.

public interface ICalculator
{
    [OperationContract]
    int Sum(int x, int y);
}

[ServiceContract]
public interface IScientificCalculator : ICalculator
{
    [OperationContract]
    int Multiply(int x, int y);
}

internal sealed class ScientificCalculator : IScientificCalculator
{
    // POST /IScientificCalculator/Sum
    public int Sum(int x, int y) { /*...*/ }

    // POST /IScientificCalculator/Multiply
    public int Multiply(int x, int y) { /*...*/ }
}

View InterfaceInheritance example.