Я играл с поддержкой DI в ASP.NET MVC RC2.
Я реализовал сеанс для каждого запроса для NHibernate и мне нужно внедрить ISession
в мой фильтр действий "Единица работы".
Если я обращаюсь непосредственно к контейнеру StructureMap (ObjectFactory.GetInstance) или использую DependencyResolver для получения моего экземпляра сеанса, все работает нормально:
ISession Session {
get { return DependencyResolver.Current.GetService<ISession>(); }
}
Однако, если я пытаюсь использовать мой StructureMap
Поставщик фильтра (наследует FilterAttributeFilterProvider
). У меня проблемы с фиксацией транзакции NHibernate в конце запроса.
Как будто ISession
объекты распределяются между запросами.Я вижу это часто, поскольку все мои изображения загружаются через контроллер MVC, поэтому я получаю около 20 сессий NHibernate, созданных при нормальной загрузке страницы.
Я добавил следующее в свой фильтр действий:
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 внедряется с использованием поставщика фильтра StructureMap.
Я обнаружил, что на странице с 20 изображениями «sessionMatch» был ложным для 2-3 запросов.
Моя конфигурация StructureMap для управления сеансом выглядит следующим образом:
For<ISessionFactory>().Singleton().Use(new NHibernateSessionFactory().GetSessionFactory());
For<ISession>().HttpContextScoped().Use(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());
В global.asax я вызываю следующее в конце каждого запроса:
public Global() {
EndRequest += (sender, e) => {
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
};
}
Безопасен ли этот поток конфигурации?Ранее я вставлял зависимости в тот же фильтр, используя пользовательский IActionInvoker
.Это работало нормально до MVC 3 RC2, когда я начал испытывать проблему, описанную выше, поэтому я подумал, что вместо этого попробую использовать поставщика фильтров.
Любая помощь будет принята.
Яиспользуя NHibernate 3 RC и последнюю версию StructureMap
Обновление:
Ниже приведены мои реализации DependencyResolver
и 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;
}
}