0

我有一个 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();
    }
}
  • grpcChannel不在请求之间重用,我认为在 NInject 中使用 Singleton 范围可以更好地注入

  • 该服务是通过CreateGrpcServiceShutdownAsync在每个操作中创建的(每个请求一次,这也很浪费),尽管我不知道在重用的 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();
}

很自然的想法是把创建ChannelILikeService移入NInject。在我看来,两者都可以作为 Singleton 注入。

剩下的唯一问题是是否必须打电话Channel.ShutdownAsync?我无法在 Ninject 中找到一种自然的方式。我只能想到两个不合理的选择:

  1. 跳过调用ShutdownAsync,我不确定后果,考虑到 ASP.NET MVC 进程本身可能被干净或不干净地关闭

  2. 把它叫进来MvcApplication.Application_End。我不确定在不正常关机的情况下是否会调用此方法。

谢谢如果有人能给我指点。

4

0 回答 0