微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 gRPC 将对象传递给 ASP.NET?

如何解决使用 gRPC 将对象传递给 ASP.NET?

我正在将一个项目从 gRPC C# 升级到 gRPC for .NET。

我正在尝试将一个对象传递给我的服务,以便在调用 gRPC 服务时采取行动。以前在 gRPC C# 中它相当简单,看起来像这样:

public class FooService : FooService.FooServiceBase
{ 
  private readonly ICustomObject _custom;

  public FooService(ICustomObject custom)
  {
     _custom = custom;
  }

  // action defined in my proto file
  public override Task<Response> SomeAction(Request request,ServerCallContext context)
  {
     return Task.Fromresult(_custom.DoAction(request))
  }
}

我可以简单地将 ICustomObject 的具体实现传递给 FooService 的构造函数,然后继续我的一天。

然后实现看起来像:

public class Bar 
{
   private Grpc.Core.Server _server;

   public void StartService(ICustomObject custom) 
   {
     _server = new Grpc.Core.Server
     {
        Services = { GrpcGeneratedServiceObject.BindService(new FooService(custom)) }
     };

     _server.Start();
   }
}

然而,在尝试将我的项目升级到 gRPC for .NET 并试图围绕 ASP.NET Core 封装我的服务后,我迷失了方向。我正在按照示例 here 进行操作,但仍然迷路了。

我发现这个建议 here,但它似乎不再适用于 ASP.NET Core 3+。

我有几个问题似乎都与我对 ASP.NET Core 中的 DI 的不完全理解有关:

  • 我是否需要在 Startup.cs 中编写自定义构造函数,然后以某种方式将其传递给配置方法
  • 我如何将 ICustomObject 的实例传递给 ConfigureStartup.cs 方法,因为它出现在 endpoints.MapGrpcService<FooService>() 这是一个按需创建的对象时?

明确地说,我之前在我的项目中使用 gRPC 的目的是抽象出我项目中必须处理网络和 TCP/IP 的问题。我能够只使用 gRPC 封装一个端点,我的项目的其余部分可以挂钩并响应/回复正在接收/发送的消息。

本质上 - 在我的各种项目中,我有许多 ICustomObject 实现需要传递给 gRPC 服务,以便根据实现会做不同的事情。目前,我不完全理解这是否可以通过 ASP.NET 实现并传入 ICustomObject 的各种实现。

解决方法

因此,过去一天我陷入了困境,试图了解 ASP.NET 依赖注入 (DI) 的工作原理,目前我找到了一个不错的解决方法。其他在 ASP.NET 和 .NET 中更有经验的人,请随时纠正我。

构造 IHostBuilder 时,我将其扩展为以下内容:

public static IHostBuilder CreateHostBuilder(string[] args,CustomObject customObject)
{
return Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        }).ConfigureServices(
            foo =>
            {
                foo.Add(new ServiceDescriptor(typeof(ICustomObject),customObject))
            });
}

在上面的 ServiceDescriptor 中,我指定了类型(在本例中为接口)和要传入的已实例化的具体对象 (customObject),如我的原始帖子中所述,{{1 }} 我正在传递ICustomObject。注释 hereherehere

对于遵循 documentation 中的 gRPC 示例的用户,Bar 中对 gRPC 服务器的调用扩展为:

Main(string[] args)

public static void Main(string[] args,CustomObject customObject) { CreateHostBuilder(args,customObject).Build().Run(); } 中,我更改了 Startup.cs 中的以下调用以添加以下内容:

ConfigureServices(IServiceCollection services)

这样 ASP.NET 就会知道对象本身。

由于 ASP.NET 在启动时需要一个具体的对象,我将抽象移出到另一个接口,该接口在其构造函数中提供给 services.AddSingleton<ICustomObject,CustomObject>(); services.AddGrpc(); ,以便 ASP.NET快乐的。否则,我会收到 this 错误“无法实例化实现类型”,根据我在该线程和其他地方读到的内容,ASP.NET 总是希望实例化一个具体的对象。

另外,谢天谢地,我不必对 CustomObject 实现进行任何更改,我将 FooService 的构造函数与之前传入的对象中的 ASP.NET 替代品相同,以执行以下操作处理。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。