Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using a Handler in Web API and having Unity resolve per request

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.

like image 225
Jamie Dixon Avatar asked Mar 18 '14 15:03

Jamie Dixon


2 Answers

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.

like image 183
Steven Avatar answered Oct 18 '22 10:10

Steven


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);
like image 12
TylerOhlsen Avatar answered Oct 18 '22 11:10

TylerOhlsen