user1765862
user1765862

Reputation: 14155

MassTransit unable to use IRequestClient - dependency injection issue

In the Startup.ConfigureServices I'm adding MassTransit configuration

services.AddMassTransit(config =>
{
       config.SetKebabCaseEndpointNameFormatter();
       config.AddRequestClient<RegisterCarOwner>();
       config.AddBus(provider => Bus.Factory.CreateUsingRabbitMq();
});
  
services.AddMassTransitHostedService();

in the handler I'm using this client in order to send message

public class RegisterCarOwnerHandler : IRequestHandler<RegisterCarOwnerCommand, Unit>
{
    private readonly IRequestClient<RegisterCarOwner> _registerOwnerClient;
    public RegisterCarOwnerHandler(IRequestClient<RegisterCarOwner> registerOwnerClient)
    {
       _registerOwnerClient = registerOwnerClient
    }

    public async Task<Unit> Handle(RegisterCarOwnerCommand command, CancellationToken token)
    {
       ...
    }
}

System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: MediatR.IRequestHandler2[xxxx.RegisterCarOwnerCommand] Lifetime: Transient ImplementationType: xxxx.TestHandler': Unable to resolve service for type 'MassTransit.IRequestClient1[RegisterCarOwner.RegisterCarOwnerHandler]' while attempting to activate 'xxxx.RegisterCarOwnerHandler '.)'

Update:

public class Startup
{
    public Startup(IConfiguration configuration) { Configuration = configuration; }
    public IConfiguration Configuration { get; }
    
    public void ConfigureServices(IServiceCollection services)
    {
        ....        
        var rabbitMqConf = new RabbitMqConfiguration();
        this.Configuration.GetSection(RabbitMqConfiguration.SectionName).Bind(rabbitMqConf);

        services.AddMassTransit(x =>
        {
            x.AddRequestClient<RegisterCarOwner>();
            x.UsingRabbitMq((context, cfg) =>
            {
                cfg.SetKebabCaseEndpointNameFormatter();
                cfg.Host(new Uri(rabbitMqConf.ConnectionUrl), c => 
                {
                    c.Username(rabbitMqConf.Username);
                    c.Password(rabbitMqConf.Password);
                });
                cfg.ConfigureEndpoints(context);
            });
        });
    }
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ....
        app.UseRouting();
        app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
    }
}   

Upvotes: 0

Views: 2490

Answers (2)

Arshia
Arshia

Reputation: 1

I had same issue when I want inject the IRequestClient<>, Based on Docs there is no need for configuration but you could do that with

A request client can be resolved using dependency injection for any valid message type, no configuration is required. By default, request messages are published and should be consumed by only one consumer/receive endpoint connected to the message broker.

x.AddRequestClient<CheckOrderStatus>

but it does work only when config this manually, or even if you use both Rabbit, InMemory you should use this after configurations.

services.AddMassTransit(x =>
{
    x.AddMessageScheduler(schedulerEndpoint);

    x.AddConsumers(assemblies);

    // Doesn`t work here :|
    x.AddRequestClient<AddComponentToMenuStructure>();

    if (Setting.General.MessageBroker == MessageBroker.RabbitMQ)
    {
        x.UsingRabbitMq((context, cfg) =>
        {
            cfg.Host(bpmsSetting.RabbitMq.Host, bpmsSetting.RabbitMq.VirtualPath, h =>
            {
                h.Username(bpmsSetting.RabbitMq.Username);
                h.Password(bpmsSetting.RabbitMq.Password);
                h.Heartbeat(TimeSpan.FromSeconds(5));
            });

            // More Config

            cfg.ConfigureEndpoints(context, new NameFormatter(bpmsSetting));
        });

    }
    else if (Setting.General.MessageBroker == MessageBroker.InMemory)
    {
         x.UsingInMemory((context, cfg) =>
            {
                // More Config
            
                cfg.ConfigureEndpoints(context, new 
NameFormatter(bpmsSetting));
            });
    }

    // Here
    x.AddRequestClient<AddComponentToMenuStructure>();
});

Upvotes: 0

Chris Patterson
Chris Patterson

Reputation: 33378

IRequestClient<T> is scoped, and you're trying to resolve it without a scope.

Also, your bus configuration is seriously outdated, change:

config.AddBus(provider => Bus.Factory.CreateUsingRabbitMq();

to the supported syntax:

config.UsingRabbitMq((context, cfg) => {});

Upvotes: 3

Related Questions