usar un controlador en la API web y tener la resolución de Unity por solicitud

Estoy usando Unity como mi marco de IoC y estoy creando un tipo basado en el valor en el encabezado de cada solicitud en un controlador:

var container = new UnityContainer(); container.RegisterType(new InjectionConstructor(valuefromHeader)); GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container); 

El problema es que SendAsync del controlador significa que el contenedor global se sobrescribe con diferentes solicitudes y que los controladores que usan IFoo en su constructor obtienen los valores incorrectos.

1) ¿Puedo hacer la sincronización SendAsync? 2) Si no es así, ¿cómo creo diferentes instancias para cada solicitud y hago que el contenedor IoC se resuelva de manera segura?

He mirado los siguientes artículos sin éxito:

http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver http://www.strathweb.com/2012/11/asp-net-web-api -y-dependencies-in-request-scope / http://benfoster.io/blog/per-request-dependencies-in-aspnet-web-api-using-structuremap

Gracias por adelantado.

Estoy de acuerdo con el enfoque de @ Steven, pero eso no responde a su pregunta más general sobre cómo resolver por solicitud.

Le recomendaría que cambie a usar UnityHierarchicalDependencyResolver y luego todo lo que registre con HierarchicalLifetimeManager se resolverá por solicitud.

Cambia esto…

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

a esto…

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

El problema que tiene se debe a que mezcla valores de tiempo de ejecución con dependencias de tiempo de diseño. En general, los servicios que resuelva del contenedor no deben depender de los valores de tiempo de ejecución en su constructor. No debe hacer esto, porque los componentes tienden a vivir mucho más tiempo que los valores de tiempo de ejecución e inyectar valores de tiempo de ejecución en los componentes, hace que sea mucho más difícil diagnosticar y verificar la configuración del contenedor.

En su lugar, oculte ese valor detrás de un servicio que puede proporcionar a los consumidores esa instancia cuando sea necesario. Por ejemplo:

 public interface IHeaderValueProvider { HeaderValue GetCurrentValue(); } 

Puede crear una implementación que se pueda registrar e inyectar fácilmente en cualquier componente que necesite ese valor. En cualquier momento después de la fase de construcción, esos componentes pueden llamar al método GetCurrentValue() en la dependencia de IHeaderValueProvider inyectada.

Logré resolver por solicitud declarando la clase de UnityResolver personalizada dentro de la clase WebApiConfig. La clase UnityResolver usa la clase HttpConfiguration suponiendo que está usando un contexto OWIN.

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

La clase ConfigureContainer es simplemente una clase donde declaro mis dependencias IOC como se muestra a continuación:

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

Es muy importante que utilice el administrador de duración de HierarchicalLifetimeManager para obtener una nueva instancia por solicitud.

La clase de UnityResolver se ve así:

 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 GetServices(Type serviceType) { try { return container.ResolveAll(serviceType); } catch (ResolutionFailedException) { return new List(); } } public IDependencyScope BeginScope() { var child = container.CreateChildContainer(); return new UnityResolver(child); } public void Dispose() { container.Dispose(); } } 

Espero que esto ayude.

Para obtener más información: http://www.asp.net/web-api/overview/advanced/dependency-injection