Closed vegar closed 4 years ago
Hum... I think maybe I'm confused - mixing up IServiceProvider
and IServiceScope
.
I assumed the IServiceProvider
you can get by doing a context.Load<IServiceProvider>
would be a scoped provider. Now, after a fifth and sixth look, my understanding is that IServiceProvider
will always be the root provider. The ServiceProviderProviderStep
will never do anything with scopes. It will only provide you the root provider handed to it during configuration. This is true for both incoming and outgoing pipeline.
Scopes on the other hand is handled only for the incoming pipeline. The activator step will create a new scope and save it for further steps - or reuse a scope if already available in the context. If the message handler sends new messages, the outgoing pipeline should be able to reuse the same scope by loading it from the context, though. Right?
I guess this issue can be closed as 'no issue'...
Yeah well.... you're correct about your observations:
IServiceProvider
in the incoming step context:var provider = context.Load<IServiceProvider();
DependencyInjectionHandlerActivator
, either
a. Uses an existing ILifetimeScope
from the incoming step context, or
b. Creates a new ILifetimeScope
(which it will then manage the lifetime of)If the message handler sends new messages, the outgoing pipeline should be able to reuse the same scope by loading it from the context, though. Right?
Yes 🙂
I guess this issue can be closed as 'no issue'...
Happy to hear that ðŸ¤
I'm not fully done, though.....
So - when sending a message from a message handler, I would need to fetch the IServiceScope
from the incoming message context throught the transaction scope. That's doable.
But - when sending a message from a web request handler, I would like to set the IServiceScope
from the http context. But as far as I can see, there is no way of getting hold of an active IServiceScope
- unless you made it yourself.
Am I overthinking this?
Should I just add an outgoing step that
IServiceScope
on the context if it founds one on the incoming context,IServiceProvider
with the one found on the HttpContext
?Any outgoing step handler needing a service provider would then need to check if there is a scope available and use that. If not, it needs to use the service provider, which might be scoped or not... ...not exactly as I would like it to be...
Do you have a better idea?
(..) when sending a message from a web request handler, I would like to set the IServiceScope from the http context. But as far as I can see, there is no way of getting hold of an active IServiceScope - unless you made it yourself (..)
I think you can resolve IHttpContextAccessor
and get the lifetime scope's service provider somewhat like this:
var context = accessor.HttpContext;
// this 👇 is the provider from the lifetime scope
var provider = context.RequestServices;
Does that help you?
When setting service provider on outgoing message pipeline, there is no check to see if there is a scoped service provider in the context already. Instead the root service provider is used.
This has implications when a message handler is sending outgoing messages. The scoped services are no longer available for the outgoing message. Isn't this a weakness? Or do I miss something here..?