I am using Unity as my IoC framework and I am creating a type based on the value in the header of each request in a handler:
var container = new UnityContainer();
container.RegisterType<IFoo,Foo>(new InjectionConstructor(valuefromHeader));
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityDependencyResolver(container);
The problem is that the handler's SendAsync
means that the global container is getting overwritten by different requests and the controllers that use IFoo in their constructor are getting the wrong values.
1) Can I make the SendAsync sync? 2) If not, how do I create different instances for each request and have the IoC container resolve safely?
I have looked at the following articles without success:
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver http://www.strathweb.com/2012/11/asp-net-web-api-and-dependencies-in-request-scope/ http://benfoster.io/blog/per-request-dependencies-in-aspnet-web-api-using-structuremap
Thanks in advance.
The problem you are having is caused by you mixing runtime values with design time dependencies. In general, the services you resolve from the container should not depend on runtime values in their constructor. You shouldn't do this, because components tend to live much longer than runtime values and injecting runtime values into components, makes it much harder to diagnose and verify the container's configuration.
Instead, hide that value behind a service that can provide consumers with that instance when required. For instance:
public interface IHeaderValueProvider
{
HeaderValue GetCurrentValue();
}
You can create an implementation that can be easily registered and injected into any component that needs that value. Anytime after the construction phase, those components can call the GetCurrentValue()
method on the injected IHeaderValueProvider
dependency.
I agree with @Steven's approach, but that doesn't answer your more general question of how to resolve per request.
I would recommend you change to using the UnityHierarchicalDependencyResolver and then anything you register with HierarchicalLifetimeManager will be resolved per request.
Change this...
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityDependencyResolver(container);
to this...
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityHierarchicalDependencyResolver(container);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With