【问题标题】:Dependency injection to a gRPC service对 gRPC 服务的依赖注入
【发布时间】:2020-05-25 11:47:13
【问题描述】:

我在带有 .NET 核心的 Visual Studio 中使用 Protobuff 创建了一个 gRPC 服务,我想测试该服务。

服务有一个构造函数:

public ConfigService(ILogger<ConfigService> logger)
{
    _logger = logger;
}

就像以某种方式注入的 ILogger(我不知道如何注入)一样,我想注入一个附加参数 - 一个接口。这个接口应该在运行时很容易设置,因为我想在运行真实运行时设置某个类,在测试时设置一个模拟类。例如:

public ConfigService(ILogger<ConfigService> logger, IMyInterface instance)
{
    _logger = logger;
    _myDepndency = instance;
}

在实际运行实例中将是new RealClass(),但在测试时很容易通过new MockClass()

启动类还是默认的:

 public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGrpcService<ConfigService>();

            endpoints.MapGet("/", async context =>
            {
                await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
            });
        });
    }
}

如何注入服务构造函数的第二个参数?

【问题讨论】:

  • 创建接口的实现或模拟并将其传递给被测对象
  • 显示测试以及您遇到问题的地方

标签: c# unit-testing dependency-injection grpc


【解决方案1】:

在最简单的形式中,您可以在ConfigureServices 方法中将您的依赖项添加到IServiceCollection

public void ConfigureServices(IServiceCollection services)
{
    services.AddGrpc();
    services.AddScoped<IMyInterface, MyClassImplementingInterface>();
}

这将在服务集合中注册您的依赖项,并使其能够通过构造函数注入自动注入。在您的测试中,您将自己注入它作为您似乎知道的模拟。

参考此链接:Dependency injection in ASP.NET Core

【讨论】:

  • 在测试中你的意思是我可以简单地自己创建服务实例?新的配置服务(空,新的 MyMock()); ?
  • 是的,类似的。您还可以查看一个模拟框架(例如 moq:github.com/Moq/moq4/wiki/Quickstart),它可以帮助您模拟您的依赖项。
  • 我注意到每次 gRPC 端点收到请求时,MyClassImplementingInterface 的构造函数都会继续运行。有什么办法可以使 MyClassImplementingInterface 只实例化一次并重新使用? (对我来说,这是每次打开一个 LMDB 数据库......这应该只发生一次!)我想我要问的是......我如何存储全局状态并从 gRPC 服务访问它以获取昂贵的实例化类图书馆?
  • 编辑:没关系。 service.AddSingleton();正在为我的用例做伎俩。
  • @DaggeJ 可能是一个迟到的问题。注册依赖后,如何在 grpc 服务中取回它?在参考链接中,它显示了我们如何在 Main() 函数 serviceScope.ServiceProvider.GetRequiredService() 中获取它。但是我怎样才能在我的 grpc 服务类中得到它呢?假设我有一个 gRPC 类 public class GreeterService: GreeterServiceBase{ public override Task SayHlelo(SayHelloRequest request, ServerCallContext context) {...} }。似乎我无法从上下文对象中获取 IServiceCollection。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
  • 1970-01-01
相关资源
最近更新 更多