mortenstarck
mortenstarck

Reputation: 2803

MassTransit automatically add consumers

Im using MassTransit to connect to our RabbitMQ. Currently im working on generalizing the code over the 15 solution that uses it. But i hit road block on the setup part. Original it looked like this:

  services.AddMassTransit(c =>
            {
                c.AddConsumer<MoveMouldConsumer>();
                c.AddBus(provider => Bus.Factory.CreateUsingRabbitMq(cfg =>
                {
                    cfg.UseHealthCheck(provider);
                    cfg.Host(MassTransitHelper.CreateRabbitMQEndpointUri(messageQueueSettings), h =>
                    {
                        h.Username(messageQueueSettings.Username);
                        h.Password(messageQueueSettings.Password);
                    });

                    cfg.PrefetchCount = (ushort) messageQueueSettings.PrefetchCount;
                    cfg.MessageTopology.SetEntityNameFormatter(new EntityNameFormatter());
                    cfg.ExchangeType = ExchangeType.Direct;
                    
                    cfg.ReceiveEndpoint(NameFormatter.FormatQueueName<MouldMovementEvent>("serviceName"), e =>
                    {
                        e.Bind(NameFormatter.FormatExchangeName<MouldMovementEvent>()); //Bind to Exchange
                        e.UseMessageRetry(r => r.Incremental(5, 5.Seconds(), 10.Seconds()));
                        e.ExclusiveConsumer = false;
                        e.PrefetchCount = messageQueueSettings.PrefetchCount;
                        e.Consumer<MoveMouldConsumer>(provider);
                        e.UseCircuitBreaker(cb =>
                        {
                            cb.TripThreshold = 15;
                            cb.ActiveThreshold = 10;
                            cb.ResetInterval = 5.Minutes();
                        });
                    });
                }));
            });

I have so far managed to generalize it to this:

services.AddMassTransit(c =>
            {
                c.AddConsumer<MoveMouldConsumer>();
                c.AddBus(provider => Bus.Factory.CreateUsingRabbitMq(cfg =>
                {
                    cfg.UseHealthCheck(provider);
                    MassTransitSetup.BasicSetup(cfg, messageQueueSettings);
                    MassTransitSetup.InitializeConsumer<MouldMovementEvent, MoveMouldConsumer>(cfg, messageQueueSettings, provider, 5, "report");
                }));
            }); 

But the part im missing is that i like to be able to automatically add all consumers by getting from Assemblies which i do like so:

var types = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(s => s.GetTypes())
            .Where(p => typeof(IConsumer).IsAssignableFrom(p) && p.IsClass && !p.IsAbstract && p.Namespace!.Contains("MST.Hepper.")).ToList();

But my problem is how to iterate through and add the c.AddConsumer<>(); or MassTransitSetup.InitializeConsumer<,>

Upvotes: 3

Views: 6797

Answers (2)

Chris Patterson
Chris Patterson

Reputation: 33542

MassTransit has methods to configure consumer automatically based on assemblies, types, etc.

services.AddMassTransit(x =>
{
    // Add a single consumer
    x.AddConsumer<SubmitOrderConsumer>(typeof(SubmitOrderConsumerDefinition));

    // Add a single consumer by type
    x.AddConsumer(typeof(SubmitOrderConsumer), typeof(SubmitOrderConsumerDefinition));

    // Add all consumers in the specified assembly
    x.AddConsumers(typeof(SubmitOrderConsumer).Assembly);

    // Add all consumers in the namespace containing the specified type
    x.AddConsumersFromNamespaceContaining<SubmitOrderConsumer>();
});

Related Documentation Link

Upvotes: 8

U.Shaba
U.Shaba

Reputation: 622

Just add an extra Select() to get assemblies implementing an empty marker interface example IMessageMarker like so:

 var assemblies = AppDomain.CurrentDomain.GetAssemblies()
                  .SelectMany(s => s.GetTypes())
                   // A marker
                  .Where(p => typeof(IMessageMarker).IsAssignableFrom(p) && p.IsClass && 
                    !p.IsAbstract && p.Namespace!.Contains("MST.Hepper."))
                  .Select(x => x.Assembly) // Get assembly
                  .ToArray();
// elided...
 c.AddConsumer(assemblies);

Upvotes: 2

Related Questions