Search code examples
c#asp.net.netdependency-injectionmediatr

MediatR register only specific handlers in an assembly with ASP.NET DI


Using the provided DI support in .NET 6, is there a way to only register specific MediatR handlers and avoid the call which does assembly scanning:

builder.Services.AddMediatR(Assembly.GetExecutingAssembly());

I'm doing some conditional configuration upon Startup and while my handlers are co-located in the same assemblies, I only want to register certain ones (and certain dependent services) based on some configuration time values.

I removed the provided AddMediatR() call and added an explicit registration for my handler:

services.AddScoped<IRequestHandler<FileProcessingRequest, ProcessingOutputDetails>, FileProcessingRequestHandler>();

But this threw an exception since IMediatR was not register.

Registering Mediator as IMediator caused another exception for a missing registration for an internal dependency of MediatR.

All of the overloads to AddMediatR() seem to want an Assembly reference(s).


Solution

  • That AddMediatR method validates that at least one assembly has been passed on which it will apply a scan looking for e.g. handlers.

    From the see source code on GitHub:

    if (!assemblies.Any())
    {
        throw new ArgumentException(
            "No assemblies found to scan. Supply at least one assembly to scan for handlers."
            );
    }
    

    Since you must pass an assembly, but at the same time you want to avoid that all handlers in your assembly get found, you can pass any other assembly that doesn't contain any handlers.

    That AddMediatR method doesn't have the requirement that it must find a handler.

    In below code the MediatR assembly itself is being passed to AddMediatR, but you can you use any other of your choice.

    The actual handlers that should be resolved can be registered manually in the way you were already doing.

    builder.Services.AddMediatR(typeof(IMediator).Assembly);
    
    builder.Services.AddScoped<IRequestHandler<FileProcessingRequest, ProcessingOutputDetails>, FileProcessingRequestHandler>();