Using Handler in the web API and allowing Unity to request

I use Unity as my IoC structure, and I create a type based on the value in the header of each request in the 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 SendAsync handler means that the global container is being overwritten by different requests, and the controllers that use IFoo in their constructor get the wrong values.

1) Can I create SendAsync synchronization? 2) If not, how do I create different instances for each request and is it safe to allow the IoC container?

I looked through 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.

+6
c # dependency-injection asp.net-web-api unity-container
source share
3 answers

I agree with @Steven's approach, but this does not answer your more general question of how to resolve the request.

I would recommend you switch to using UnityHierarchicalDependencyResolver, and then everything that you register in the HierarchicalLifetimeManager will be allowed for each request.

Change it ...

 GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container); 

to that...

 GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityHierarchicalDependencyResolver(container); 
+11
source share

The problem you are facing is caused by a mix of runtime values ​​with development-time dependencies. In general, the services you allow from the container should not depend on the runtime values ​​in their constructor. You should not do this, because components tend to live much longer than run-time values, and introduce run-time values ​​into components, making it difficult to diagnose and verify the configuration of the container.

Instead, hide this value behind a service that can provide consumers with this instance when needed. For example:

 public interface IHeaderValueProvider { HeaderValue GetCurrentValue(); } 

You can create an implementation that can be easily registered and inserted into any component that needs this value. At any time after the construction phase, these components can call the GetCurrentValue() method for the IHeaderValueProvider nested dependency.

+3
source share

I managed to solve each request by declaring my custom class UnityResolver in the WebApiConfig class. The UnityResolver class uses the HttpConfiguration class, assuming you are using an OWIN context.

 public static void Register(HttpConfiguration config) { // Web API configuration and services var _container = new UnityContainer(); DependencyConfiguration.ConfigureContainer(_container); config.DependencyResolver = new UnityResolver(_container); } 

The ConfigureContainer class is just a class where I declare my IOC dependencies, as shown below:

 private static void RegisterReleaseEnv(IUnityContainer container) { //Repository Registration container .RegisterType(typeof(IRepository<>), typeof(GenericRepository<>), new HierarchicalLifetimeManager()); } 

It is very important that you use the HierarchicalLifetimeManager lifecycle manager to get a new instance for each request.

The UnityResolver class is as follows:

 public class UnityResolver : IDependencyResolver { protected IUnityContainer container; public UnityResolver(IUnityContainer container) { if (container == null) { throw new ArgumentNullException("container"); } this.container = container; } public object GetService(Type serviceType) { try { return container.Resolve(serviceType); } catch (ResolutionFailedException) { return null; } } public IEnumerable<object> GetServices(Type serviceType) { try { return container.ResolveAll(serviceType); } catch (ResolutionFailedException) { return new List<object>(); } } public IDependencyScope BeginScope() { var child = container.CreateChildContainer(); return new UnityResolver(child); } public void Dispose() { container.Dispose(); } } 

Hope this helps.

For more information: http://www.asp.net/web-api/overview/advanced/dependency-injection

0
source share

All Articles