Каков правильный способ внедрения канала Grpc и службы grpc в ASP.NET MVC (не .NET Core) с особым учетом изящной синхронизации ShutdownAsync?

#c# #asp.net-mvc #grpc #protobuf-net.grpc

Вопрос:

У меня есть ASP.NET Проект MVC, который использует NInject в качестве IOC и protobuf-net.Grpc для вызова служб grpc с использованием кода в первую очередь.

В настоящее время он используется так (полностью пропуская IOC), который явно имеет много запахов кода.

 public class LikeApiController : BaseApiController
{
    private readonly Channel _channel;

    public LikeApiController()
    {
        _channel = new Channel(/* port, host, etc ...*/);
    }

    [HttpPost]
    public async Task<IHttpActionResult> LikeAsync(LikeType likeType, long targetId)
    {
        try
        {
            ILikeService client = _channel.CreateGrpcService<ILikeService>();
            await client.LikeAsync(new LikeRequest /* omitted */);
        }
        finally
        {
            await _channel.ShutdownAsync();
        }
        return Ok();
    }
}
 
  • grpc Channel не используется повторно между запросами, которые, я думаю, можно было бы лучше ввести с помощью одноэлементной области в NInject
  • Служба создается с помощью CreateGrpcService и ShutdownAsync в каждом действии (один раз на запрос, что также является расточительным), хотя я не знаю, сколько накладных расходов требуется для создания службы grpc поверх повторно используемого экземпляра канала grpc.

Несмотря на запах кода, по крайней мере, он строго следует protobuf-net.Grpc руководству:

 var channel = new Channel("localhost", 10042, ChannelCredentials.Insecure);

try
{
    var calculator = channel.CreateGrpcService<ICalculator>();
    await Test(calculator);
}
finally
{
    await channel.ShutdownAsync();
}
 

Естественное мышление состоит в том, чтобы переместить создание Channel и ILikeService в девяностый объект. На мой взгляд, оба могут быть введены как Синглтон.

Осталась единственная проблема-обязательно ли звонить Channel.ShutdownAsync ? Я не мог придумать естественный способ в Ninject. Я мог думать только о двух неразумных вариантах:

  1. Пропустите звонки ShutdownAsync , в чем я не уверен в последствиях, учитывая, что ASP.NET Сам процесс MVC может быть отключен либо чисто, либо нечисто
  2. Позвони ему MvcApplication.Application_End . Я не уверен, что этот метод будет вызван в случае нечистого завершения работы.

Спасибо, если кто-нибудь может дать мне указания.