web-dev-qa-db-ja.com

MassTransitと.NET Core DI-パラメーターのないコンストラクターで依存関係を解決する方法は?

私は.NET Core 2とMassTransit 4(dev)を使用してアプリに取り組んでいます。

Mass Transitでは、コンシューマー向けにパラメーターのないコンストラクターが必要です。使用する必要があります。私のコンシューマーではロガー、dbContextなどがあり、.NET CoreのネイティブDIを引き続き使用したいので、(可能な場合は)Autofacなどを追加する必要はありません。私のコンシューマーがパラメーターなしのコンストラクターで作成されているため、.NET Core DIが私のdepを挿入できないときに問題が発生しています...

パラメーターなしのコンストラクターを使用しながらネイティブネットコアDIを使用して依存関係を解決する方法はありますかOR 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'.

私はどんな助けにも感謝します。私が何を求めているのかはっきりしているといいのですが。

8

Microsoft.Extensions.DependencyInjectionコンテナー(ASP.NET Coreのデフォルト)を使用している場合、MassTransitには MassTransit.Extensions.DependencyInjection パッケージが必要です。パッケージは現在プレリリース版としてのみ入手可能であり、MassTransitのプレリリース版も必要です。さらに、新しいパッケージは 。NET Standardの大規模な移行 の一部であり、まだ完全ではないため、かなりの数の可動部分がある可能性があるため、少し注意する必要があります最終リリースまで。

パッケージは正式にリリースされていないため、まだドキュメントはありません。しかし、 それを導入したプルリクエスト現在のソース を見ると、次のことが必要だと思います。

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);
});

whereについては(これもサービスプロバイダーにアクセスするために)これを行う必要があります。StartupConfigureメソッド。このメソッドは、依存関係を引数として取ることができるため、サービスプロバイダーを簡単に注入できます。

public void Configure(IApplicationBuilder app, IServiceProvider serviceProvider, IApplicationLifetime applicationLifetime)
{
    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.LoadFrom(serviceProvider);
        });
    });

    // start/stop the bus with the web application
    applicationLifetime.ApplicationStarted.Register(bus.Start);
    applicationLifetime.ApplicationStopped.Register(bus.Stop);
}

ただし、最後の免責事項:私はMassTransitを個人的に使用したことがないため、これがライブラリにとって実際に意味があるかどうかはわかりません。

16
poke

私も同じ問題があり、IBusIPublishEndpoint、およびISendEndpointProviderにDIを使用する必要があったため、pokeの回答がうまくいきませんでした。私は実際にこのまさに質問に反対票を投じて削除された回答に解決策を見つけました。それは私を助けたので本当に恥。

私はこの例を見つけました ここ

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

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