我有一个 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 中使用 Singleton 范围可以更好地注入该服务是通过
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
移入NInject。在我看来,两者都可以作为 Singleton 注入。
剩下的唯一问题是是否必须打电话Channel.ShutdownAsync
?我无法在 Ninject 中找到一种自然的方式。我只能想到两个不合理的选择:
跳过调用
ShutdownAsync
,我不确定后果,考虑到 ASP.NET MVC 进程本身可能被干净或不干净地关闭把它叫进来
MvcApplication.Application_End
。我不确定在不正常关机的情况下是否会调用此方法。
谢谢如果有人能给我指点。