He estado jugando con el soporte DI en ASP.NET MVC RC2.Acción Filtro Dependencia Inyección en ASP.NET MVC 3 RC2 con StructureMap
He implementado sesión por solicitud para NHibernate y necesito inyectar ISession
en mi filtro de acción "Unidad de trabajo".
Si me refiero al contenedor StructureMap directamente (ObjectFactory.GetInstance) o utilizar DependencyResolver para conseguir mi instancia de sesión, todo funciona bien:
ISession Session {
get { return DependencyResolver.Current.GetService<ISession>(); }
}
Sin embargo, si intento utilizar el profesional de filtro de StructureMap
(hereda FilterAttributeFilterProvider
) Tengo problemas para comprometer la transacción de NHibernate al final de la solicitud.
Es como si los objetos ISession
se están compartiendo entre las solicitudes. Estoy viendo esto con frecuencia, ya que todas mis imágenes se cargan a través de un controlador MVC, así que obtengo unas 20 sesiones de NHibernate creadas en una carga de página normal.
que añade lo siguiente a mi filtro de acción:
ISession Session {
get { return DependencyResolver.Current.GetService<ISession>(); }
}
public ISession SessionTest { get; set; }
public override void OnResultExecuted(System.Web.Mvc.ResultExecutedContext filterContext) {
bool sessionsMatch = (this.Session == this.SessionTest);
SessionTest se inyecta mediante el proveedor StructureMap filtro.
Encontré que en una página con 20 imágenes, "sessionsMatch" era falso para 2-3 de las solicitudes.
Mi configuración StructureMap para la gestión de sesiones es el siguiente:
For<ISessionFactory>().Singleton().Use(new NHibernateSessionFactory().GetSessionFactory());
For<ISession>().HttpContextScoped().Use(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());
En Global.asax que llamar al siguiente al final de cada solicitud:
public Global() {
EndRequest += (sender, e) => {
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
};
}
¿Este hilo configuración segura? Previamente estaba inyectando dependencias en el mismo filtro usando un IActionInvoker
personalizado. Esto funcionó bien hasta MVC 3 RC2 cuando comencé a experimentar el problema anterior, por lo que pensé que trataría de usar un proveedor de filtros.
Cualquier ayuda sería apreciada.
estoy usando NHibernate 3 RC y la última versión de StructureMap
Actualización:
continuación son mis implementaciones de DependencyResolver
y FilterAttributeFilterProvider
:
public class StructureMapDependencyResolver : IDependencyResolver {
private readonly IContainer container;
public StructureMapDependencyResolver(IContainer container) {
this.container = container;
}
public object GetService(Type serviceType) {
var instance = container.TryGetInstance(serviceType);
if (instance==null && !serviceType.IsAbstract){
instance = AddTypeAndTryGetInstance(serviceType);
}
return instance;
}
private object AddTypeAndTryGetInstance(Type serviceType) {
container.Configure(c=>c.AddType(serviceType,serviceType));
return container.TryGetInstance(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType) {
return container.GetAllInstances(serviceType).Cast<object>();
}
}
public class StructureMapFilterAttributeFilterProvider : FilterAttributeFilterProvider
{
private readonly IContainer container;
public StructureMapFilterAttributeFilterProvider(IContainer container) {
this.container = container;
}
protected override IEnumerable<FilterAttribute> GetControllerAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
return BuildUp(base.GetControllerAttributes(controllerContext, actionDescriptor));
}
protected override IEnumerable<FilterAttribute> GetActionAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
return BuildUp(base.GetActionAttributes(controllerContext, actionDescriptor));
}
private IEnumerable<FilterAttribute> BuildUp(IEnumerable<FilterAttribute> attributes) {
foreach (var attr in attributes)
container.BuildUp(attr);
return attributes;
}
}
Estoy buscando un problema similar. – Craig