Register all IMediatR classes

58 views Asked by At

Is there any form to avoid registering all the assemblies that implement IMediator service?

I try using these options but none of them helps me:

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

builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()))

Currently the only option that works for me is if I register all the services like this:

builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(MYQUERY).Assembly));

But this is very tedious because my program.cs will have a lot of lines, is there any other option to do this?

1

There are 1 answers

3
Guru Stron On BEST ANSWER

But this is very tedious because my program.cs will have a lot of lines

Personally I would go with the "manual" approach. If you don't want to "litter" the Program.cs then you can always move this part of the setup to some extension method:

public static class MediatrRegistrationExts
{
    public static IServiceCollection AddMediatorWithAll(this IServiceCollection services)
    {
        var types = new[]
        {
            typeof(MediatrAssemlyOneLandmark),
            typeof(MediatrAssemlyTwoLandmark)
        };
        services.AddMediatR(types.Select(t => t.Assembly).ToArray());
        return services;
    }
} 

And then:

builder.Services.AddMediatorWithAll();

But if you really-really want to go full dynamic mode then you can try something like the following (not tested):

builder.Services.AddMediatR(GetAllAssemblies().ToArray());

static IEnumerable<Assembly> GetAllAssemblies()
{
    var assemblies = new HashSet<string>();
    var stack = new Stack<Assembly>();

    stack.Push(Assembly.GetEntryAssembly());

    while (stack.Count > 0)
    {
        var asm = stack.Pop();

        yield return asm;

        foreach (var reference in asm.GetReferencedAssemblies())
        {
            if (!assemblies.Contains(reference.FullName))
            {
                stack.Push(Assembly.Load(reference));
                assemblies.Add(reference.FullName);
            }
        }

    }
}

But I highly recommend against it.

P.S.

Make sure that you have actually those types placed in different assemblies because based on the comments it is highly likely they are actually in a single assembly.