MediatR in Class Library
I have an application that's broken up in 3 parts: API, Blazor, and Class Library. The Class Library contains all of the business logic. I want to start using the Notification pattern supplied by Mediatr to coordinate some of the more complex operations my application performs. However, I'm not sure how to instantiate or even use MediatR in a class library.
All the examples on the internet show that you must register MediatR with the IServiceCollection. But my use of MediatR will be strictly within the Class Library, which does not have an IServiceCollection (I use a custom IFactory to manually inject inside the Class Library). I could of course use the one provided by the API and pass it into the Class Library, but after that, I'm not quite sure how the INotification implementations are supposed to be instantiated in the Class Library when they require injections that are internal to the Class Library and not exposed at all to the API.
16 Replies
Here's an example:
My application is a financial application for managing budgets. When I add to the ledger, several types of balances need to be adjusted. I want to coordinate these updates using the INotification pattern. The problem is I have no idea how MediatR is supposed to have these three interfaces injected when they are not exposed at all to the API layer. I could of course expose them and their implementations, and have the API's IServiceCollection manage it instead of my own custom factory. But then that makes me wonder if there's any point to having all the business logic in the Class Library.
Inside the class library write an extension method for
IServiceCollection
that does all the registration and has - of course - access to all internal types. Name that method UseBusinessLogic
. Call that extension method from the Api project services.UseBusinessLogic();
.Thank you very much! I didn’t know these things were possible. I’ll do some research later tonight when I have some free time
Well MediatR does it too
https://github.com/jbogard/MediatR/blob/master/src/MediatR/MicrosoftExtensionsDI/ServiceCollectionExtensions.cs
GitHub
MediatR/src/MediatR/MicrosoftExtensionsDI/ServiceCollectionExtensio...
Simple, unambitious mediator implementation in .NET - jbogard/MediatR
Yes, I see that now. Until now, it never really clicked as to what was going on behind the scene with the IServiceCollection.
I hope you don't mind if I ask you another question. I've only ever really used the IServiceCollection in blazor and API projects, where any interfaces I declare are injected for me automatically. How would I use IServiceCollection in the class library to create instances? Do I pass the IServiceCollection object itself into the library? Or does it compile to something else? Sorry, I've been doing some googling, and haven't been able to find an answer
You resolve from
IServiceProvider
- the ServiceCollection is for setup that provider
It is possible to inject IServiceProvider
but you should not. f.i. if you need to create some HttpClient instances, then inject an IHttpClientFactory
and use that for creation.So in my API, I just inject the IServiceProvider like this, and I can use the provider to create instances using the GetService<T>?
Yes, but you should not
Hmm, okay.
Oh, is it GetRequiredService<T>?
Because you know what services you need, then inject that services instead of
IServiceProvider
Oh I see what you mean.
That will be some serious change with how I'm doing things on my end, but I'm fine making it.
Thank you, you've been a big help @Sir Rufo !
👍
Also worth noting you would only need to use the MediatR.Contracts package in your class library and inject IMediator into your classes
You mean, by using MediatR’s request/response and notification systems, MediatR will handle any surplus injections?
Yeah basically inject it into the constructor
Excellent. It’s all becoming clear to me now. Thank you 😊