MassTransit和.NET Core DI - 如何使用无参数构造函数解决依赖关系?

时间:2017-12-23 16:33:59

标签: c# asp.net-core .net-core masstransit

我正在使用.NET Core 2和MassTransit 4(dev)开发应用程序。

Mass Transit需要为消费者提供无参数构造函数。 我需要使用例如在我的消费者中使用logger,dbContext等,我想继续使用.NET Core中的原生DI,所以我不想添加Autofac等(如果可能的话)。当.NET Core DI无法注入我的deps时会导致问题,因为我的使用者是使用无参数构造函数创建的...

有没有办法在使用无参数构造函数的情况下使用本机网络核心DI来解决依赖关系或者是否有某种方式来声明MassTransit的端点,这将允许执行除标准之外的其他操作:

sbc.ReceiveEndpoint(host, Configuration["QueueName"], 
                    e => { e.Consumer<MyAwesomeConsumer>();});

我尝试过:

// =========== MASS TRANSIT ===============
            var serviceProvider = services.BuildServiceProvider();
            services.AddSingleton<MyAwesomeConsumer, MyAwesomeConsumer>();
            var bus = Bus.Factory.CreateUsingRabbitMq(sbc =>
            {
                var host = sbc.Host(new Uri("rabbitmq://localhost"), h =>
                {
                    h.Username("guest");
                    h.Password("guest");
                });

                sbc.ReceiveEndpoint(host, Configuration["QueueName"],
                    e =>
                    {
                        e.Consumer(typeof(MyAwesomeConsumer), serviceProvider.GetService);
                    });
            });

应用程序提升但第一条消息一到,我就收到错误:MassTransit.ConsumerException: Unable to resolve consumer type 'AuthService.Integrations.MyAwesomeConsumer'.

我将不胜感激任何帮助。 我希望我的问题很清楚。

2 个答案:

答案 0 :(得分:14)

如果您正在使用Microsoft.Extensions.DependencyInjection容器(这是ASP.NET Core的默认容器),那么您将需要MassTransit的MassTransit.Extensions.DependencyInjection包。请注意,该软件包目前仅作为预发布版本提供,还需要预发布版本的MassTransit。此外,新包是a massive migration for .NET Standard的一部分,但仍然不完整,所以你可能会有点小心,因为在最终版本发布之前可能会有很多移动部件。

由于软件包尚未正式发布,因此还没有任何文档。但是通过查看the pull request that introduced itthe current source,我认为您需要做的是以下内容:

Startup.ConfigureServices中,您需要添加MassTransit,就像添加其他服务一样:

services.AddMassTransit(c =>
{
    c.AddConsumer<MyConsumer>();
    c.AddConsumer<MyOtherConsumer>();

    // or sagas
    c.AddSaga<MySaga>();
});

// you still need to register the consumers/sagas
services.AddScoped<MyConsumer>();
services.AddScoped<MyOtherConsumer>();
services.AddSingleton<ISagaRepository<MySaga>, InMemorySagaRepository<MySaga>>();

在配置操作中,您需要注册消费者和传奇,以便MassTransit稍后妥善解决它们。

然后,在您的总线配置中,您可以与服务提供商联系LoadFrom

sbc.ReceiveEndpoint(host, Configuration["QueueName"], e =>
{
    e.LoadFrom(serviceProvider);
});

至于你应该这样做(也是为了能够访问服务提供商),我建议你在Startup的{​​{1} {{1} } 方法。该方法可以将任何依赖作为参数,因此您可以轻松地在那里注入服务提供者:

Configure

尽管有一个最后的免责声明:我个人没有使用过MassTransit,所以我真的不知道这是否对图书馆有实际意义。

答案 1 :(得分:1)

我也遇到了同样的问题,因为我需要为IBusIPublishEndpointISendEndpointProvider使用DI,所以戳的答案对我不起作用。其实,我发现这个问题很向下投中已删除的答案的解决方案。真是耻辱,因为它帮助了我。

我发现了这个例子here

services.AddSingleton(provider => Bus.Factory.CreateUsingRabbitMq(cfg =>
{
   var host = cfg.Host("localhost", "/", h => { });

   cfg.ReceiveEndpoint(host, "web-service-endpoint", e =>
   {
      e.Consumer<DoSomethingConsumer>(provider);
   });
}));