Injecting IRequestClient in singleton services with M.E.DI
See original GitHub issueHey, I’ve noticed that the registration of request clients with Microsoft.Extensions.DependencyInjection looks like this:
So an IRequestClient<T>
is registered both as a scoped and a singleton service. Note that this does not work with M.E.DI and only the latter registration is used when providing a service. So since the scoped registration comes last, every injection happens based on this registration.
This can become problematic when injecting the request client into singleton services because then this is basically violating the service scoping. If you have enabled validateScope
when building the service provider this will cause a runtime exception:
InvalidOperationException: Error while validating the service descriptor ‘ServiceType: ExampleProject.IExampleService Lifetime: Singleton ImplementationType: ExampleProject.ExampleService’: Cannot consume scoped service ‘MassTransit.IRequestClient`1[ExampleProject.ExampleRequestMessage]’ from singleton ‘ExampleProject.IExampleService’.
Unfortunately, there isn’t really a way to remedy this, apart from registering the singleton client using a different type but I’m not sure if that’s a nice solution here. I personally just inject the IClientFactory
now and just create the client there.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:14 (13 by maintainers)
The resulting clients are, in fact, thread safe.
So, yeah, the singleton (non-scoped) version is going to have to be built on-demand using the
IClientFactory
as you are doing. I’m going to add a couple of extension methods to help out, but I don’t see any other way around it.