web-dev-qa-db-fra.com

MassTransit et .NET Core DI - Comment résoudre les dépendances avec un constructeur sans paramètre?

Je travaille sur l'application avec .NET Core 2 et MassTransit 4 (dev).

Mass Transit nécessite un constructeur sans paramètre pour les consommateurs ..__ Je dois utiliser par exemple logger, dbContext, etc. dans mes clients et je voudrais continuer à utiliser l’ID natif de .NET Core afin de ne pas avoir à ajouter Autofac, etc. (si possible?). Cela cause le problème lorsque .NET Core DI ne peut pas injecter mes comptes car mon consommateur est créé avec un constructeur sans paramètre ...

Existe-t-il un moyen de résoudre les dépendances à l’aide de l’ID net core natif tout en ayant le constructeur sans paramètre OR? Existe-t-il un moyen de déclarer les points de terminaison de MassTransit permettant de le faire autrement que par défaut:

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

J'ai essayé:

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

L'application se soulève mais dès que le premier message arrive, je reçois une erreur: MassTransit.ConsumerException: Unable to resolve consumer type 'AuthService.Integrations.MyAwesomeConsumer'.

Je vais apprécier toute aide. J'espère que ce que je demande est clair.

7
M U

Si vous utilisez le conteneur Microsoft.Extensions.DependencyInjection (qui est le port par défaut avec ASP.NET Core), vous aurez besoin du package MassTransit.Extensions.DependencyInjection pour MassTransit. Notez que le package est actuellement disponible uniquement en tant que version préliminaire et nécessite également une version préliminaire de MassTransit. En outre, le nouveau package fait partie de une migration massive pour .NET Standard , qui n’est toujours pas terminée. Vous devez donc être un peu prudent car il y aura probablement quelques pièces mobiles jusqu’à la finale Libération.

Comme le paquet n’est pas officiellement publié, il n’ya pas encore de documentation dessus. Mais en regardant la demande d'extraction qui l'a introduite et la source actuelle , je pense que ce que vous devez faire est la suivante:

Dans Startup.ConfigureServices, vous devez ajouter MassTransit, comme vous le feriez avec d'autres services:

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

Dans l'action de configuration, vous devez enregistrer vos consommateurs et vos sagas pour que MassTransit puisse les résoudre correctement ultérieurement.

Ensuite, dans votre configuration de bus, vous appelez LoadFrom avec le fournisseur de service:

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

En ce qui concerne where, vous devez le faire (également pour pouvoir accéder au fournisseur de services). Je vous suggère donc de le faire avec votre méthode Startup’s s Configure. La méthode peut prendre n'importe quelle dépendance comme argument. Vous pouvez donc facilement y injecter le fournisseur de services:

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

Un dernier avertissement cependant: je n’ai personnellement pas utilisé MassTransit, je ne sais donc pas vraiment si cela a un sens réel pour la bibliothèque.

13
poke

J'avais également le même problème et la réponse de poke ne fonctionnait pas pour moi car je devais utiliser DI pour IBus, IPublishEndpoint et ISendEndpointProvider. J'ai en fait trouvé la solution dans une réponse supprimée avec un vote négatif sur cette question même. Honte vraiment car cela m'a aidé.

J'ai trouvé cet exemple ici

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

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