Home > Software engineering >  How do I configure the IMediator (MassTransit) passed into a controller, using Autofac?
How do I configure the IMediator (MassTransit) passed into a controller, using Autofac?

Time:11-06

I have the following .Net controller (highly simplified) that does something like this:

public class FooController{
    private MassTransit.Mediator.IMediator mediator;
        
    public FooController(MassTransit.Mediator.IMediator mediator)       
    {
        this.mediator = mediator;       
    }

    [HttpPost]
    public async Task CreateFooJob(FooJobRequest myRequest){
        var client = mediator.CreateRequestClient<GoCreateJobRequest>();
        var response = await mediator.GetResponse<GoCreateJobResponse>(new GoCreateJobRequest(myRequest));
        return; 
    }
    public class GoCreateJobConsumer : IConsumer<GoCreateJobRequest>{
        //some work...
        await context.ResponseAsync<GoCreateJobResponse>(new GoCreateJobResponse());
    }
     
}

I am struggling with initialising the IMediator object using Autofac. The MassTransit documentation seems to think that something like this:

builder.AddMediator(c =>
{
    c.AddConsumer<GoCreateJobConsumer>();

});

Should work, but it does not - it does not connect the IMediator to a mediator object (which, makes sense since Autofac does not have anything registered for that). Instead, my WebApiConfig code looks like this (idea taken from the "Configuration" section of this page of documntation:

var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
build.Register(m => MassTransit.Bus.Factory.CreateMediator(cfg =>
    {
        cfg.Consumer<GoCreateJobConsumer>();
    })
);
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

This was actually working fairly nicely - when I debugged through my controller, I was able to step into the request. However, upon returning the response it failed and said "loopback://localhost/response => The message was not consumed".

I feel like I have scoured the internet and SO to get the answer to how to configure this thing, and I can't figure it out. Is there something I'm missing?? I feel like I'm missing something related to the Factory or Bus idea in the mediator configuration. Is there another way I should be approaching writing the controller that still gives me some D.I. but makes these configuration stuff work?? Thank you

CodePudding user response:

According to the available source code, builder.AddMediator(... is a valid extension and should work.

Simplified example

//...

var builder = new ContainerBuilder();

//add controllers
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

//setup mass transit
builder.AddMassTransit(x => {
    //...omitted for brevity
});

//configure mediator
builder.AddMediator(c => {
    c.AddConsumer<GoCreateJobConsumer>();    
});

var container = builder.Build();

config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

//...

CodePudding user response:

I figured it out! @Nkosi was correct that the builder.AddMediator function should be used to initialize it. However, the syntax is a bit off. Looking at the linked documentation, the AddMediator function returns a modified builder object. I'm not 100% sure why this worked, but returning the builder object and reassigning it to itself solved my problem. My code ends up looking like this:

var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder = builder.AddMediator(c => {
    c.AddConsumer<GoCreateJobConsumer>();    
});

Thank you Nkosi!

  • Related