In a Web API, I have a service that depends on IMessageSession. However, the pipeline used to send messages does not have access to the scoped ServiceProvider.
I have implemented Behavior<IOutgoingLogicalMessageContext> and want to access our scoped TenantProvider to set a tenant header on outgoing messages. The problem is that the ServiceProvider available in the pipeline is the root container; hence, trying to resolve a scoped service results in an exception.
var scopedProvider = context.Extensions.Get<IServiceProvider>();
var tenantProvider = scopedProvider.GetRequiredService<TenantProvider>();
@Stig_Christensen To resolve scoped services use context.Builder.GetRequiredService<ScopedDependency>(); as shown in the below snippet:
public class BehaviorUsingDependencyInjection :
Behavior<IIncomingLogicalMessageContext>
{
// Dependencies injected into the constructor are singletons and cached for the lifetime
// of the endpoint
public BehaviorUsingDependencyInjection(SingletonDependency singletonDependency)
{
this.singletonDependency = singletonDependency;
}
public override async Task Invoke(IIncomingLogicalMessageContext context, Func<Task> next)
{
var scopedDependency = context.Builder.GetRequiredService<ScopedDependency>();
// do something with the scoped dependency before
await next();
// do something with the scoped dependency after
}
SingletonDependency singletonDependency;
}
I see there is a builder that is convenient. But my problem is that this is an IOutgoingLogicalMessageContextbehaviour, and the container is not scoped. Even though the IMessageSession(that sends the message) is a dependency in a scoped API controller, I still get:
System.InvalidOperationException: Cannot resolve scoped service 'TenantProvider' from root provider.