First of all, thanks for a great library, makes life and code so much easier.
The issue I am struggling with, I am not sure if it is .NET Core (3.1) or MediatR issue, but suppose you have the following setup
Common (library)
Service A
Service B
Now if you have a handler set S that are common across the services it may make sense to put them in the common lib, but A may need a subset and B may need another subset, not necessary overlapping.
What happens though, when you add the common assembly in the addMediatR in A or B is that it finds all the handler types in S and tries to resolve them, which is not guranteed as some dependencies are only available in A and others only available in B.
How do you work around this without duplicating the handlers? I am guessing it is not easy to solve as you would essentially have to scan out from the executing assembly to find all the handler types actually being referenced.
Typically your calling application has access to all of those libraries, and configures your container to be able to resolve all of those things.
Are your Service A and Service B different applications, and those have the implementations to dependencies defined in Common? If that's the case, then I'd just move those implementations to Common, since they are, common.
I'm also experiencing the same need.
Guessing that it is a common scenario to have several executable applications reference the same common library in one solution, but not using all the handlers defined there.
However, in such case (described by @arynaq) InvalidOperationException: Unable to resolve service <..> is thrown by DI framework on startup.
It would be very useful to be able to filter out classes in assemblies by namespace or an easy way to register single handlers.
Any workaround suggestions would be appreciated.
A few options:
AddMediatR) when you register the handlersI'm also having this same issue.
@jbogard concerning the workarounds:
I'm adding my voice to previous ones. I think it would help to have a way to filter types that MediatR can scan. Maybe have an overload that accepts IEnumerable<TypeInfo> instead of only accepting IEnumerable<Assembly>.
@disklosr not sure what you mean by Option1. Are you saying that your "services" are small enough that they would only have 1 or 2 handlers, so instead you put them in the common project?
If you need more complex filtering / scanning for DI registration it might be worthwhile to use a different DI rather than the dotnet core DI (the AddMediatR function is only for the built in DI). There are examples of how to do this with popular DI frameworks.
It sounds like all of this are workarounds to design smells, to me. You shouldn't put handlers in a common library if they're not actually common. I don't know why you'd end up with lots of projects with only 1-2 handlers - you already have lots of projects because you have lots of applications. Just put the handlers in the application projects.
@lilasquared I meant that I have many independent handlers (not necessarily small) that if I split them I'll end up with lots of projects having.
Switching IoC containers seems a reasonable thing to do as this is really about scanning and registering handlers.
But if AddMediatR exists for the sole purpose of facilitating registration of handlers for those who decide to use the bare-bone dotnet built-in IoC container, then it might as well facilitate filtering.
@jbogard my handlers belong to the Application layer, my aspnet core projects are in UI layer, I do not want to mix the two.
I chose to combine all handlers in the same project first even if they're not actually common, and will split them progressively as needed.
My architecture is based on this if you need to see an example https://github.com/jasontaylordev/CleanArchitecture
only difference is I have sevral UI projects and one common project sharing all the handlers.
I'm not following the problem you're having any more. If all your handlers are defined in the application layer project, which should only have the one dependency of the domain layer project, then service A will just have access to all handlers when they are registered. Why do you have a need to filter the handlers so that different ones are registered to service A than to service B?
If you're having these problems, it's a sign that your architecture is wrong, not the library.
And I'm trying to be gentle here because I made these exact same mistakes about 10-12 years ago - but if you have to make a library or container go through all these convoluted gymnastics to get your application architecture to work properly, it's not the fault of the library/container. It's the fault of the architecture. It isn't actually simplifying things - it only gives the illusion of simplicity because code exhibits some organizational structure.
Just use folders for organization. It's fine. And vastly, vastly simpler. Use projects for units of shareable, deployable code.
@lilasquared arynac's description explains it well imo.
Let's say I have service A that uses Handler A that uses Dep A
Plus another service B that uses Handler B that uses Dep B
In service A, I register Dep A but not Dep B since it's not needed.
When I call AddMediatR() it registers Handler A and Handler B.
When I start Service A, the IoC container complains at startup because Handler B was registered but it can't be resolved since its dependency hasn't been registered.
If you have a handler in a common layer, with a dependency, then the dependency must be a common dependency too. Otherwise you don't have a common handler, and your "common" layer is not logically a common layer. The point of common is that anything can use it. If that's not the case then something is wrong there.
This could be considered "a problem" of the .net core DI engine, not this library. Also is a design problem because something that is common, at the end is not. You should consider splitting the common into 2 or 3 or N "common" libraries, and that should solve the problem too
Hello from Twitter 馃憢
Here's a visual representation of what I believe is the architecture being described here.

If this is your architecture then I think the best thing you can do is move the handlers to the service assemblies. Organizing types by type-of-thing (service, interface, handler, controller, model, view) is a practice that doesn't scale well. You just discovered one reason why.
Alright it seems everyone here is suggesting that all this smells an architectural issue and that it's not really the fault of this library. Fair enough. I thank you all for trying to help and do respect all of your opnion and advice and will definnetly take them into consideration.
To me the problem I'm facing is ultimately a limitation of the DI library which is not being able to discover types at a finer level than an Assembly, and I do agree it is not the responsability of this library to make up for this.
I'd like to clarify some things:
Most of you suggested to put handlers in my UI layer. Here are my current thoughts on this:
I'll try to rethink my architecture through and will consult other people on this. Would love to hear what @arynaq and @domasd think about this.
Again, thank you all for your contributions!
To be clear, I'm suggesting not just moving your handlers to your UI project, but to get rid of all of the layers altogether:
https://vimeo.com/131633177
https://www.youtube.com/watch?v=SUiWfhAhgQw
The issue is conflating LOGICAL boundaries with PHYSICAL ones. You're not violating some fundamental law by using folders instead of projects to organize. And as you've found, you have to bend and twist your DI container to do these indirection tricks (or multiply your projects).
And knowing several DI container authors personally, they *hate* this architecture because it tries to force the DI container to do far more than it ever was designed to be. You won't get much more help from those folks either 馃槅
Good luck!
Most helpful comment
And I'm trying to be gentle here because I made these exact same mistakes about 10-12 years ago - but if you have to make a library or container go through all these convoluted gymnastics to get your application architecture to work properly, it's not the fault of the library/container. It's the fault of the architecture. It isn't actually simplifying things - it only gives the illusion of simplicity because code exhibits some organizational structure.
Just use folders for organization. It's fine. And vastly, vastly simpler. Use projects for units of shareable, deployable code.