【发布时间】:2010-12-17 00:01:24
【问题描述】:
我一直在使用 ASP.NET MVC RC2 中的 DI 支持。
我已经为 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 张图片的页面上,“sessionsMatch”对于 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;
}
}
【问题讨论】:
-
我发现了一个类似的问题。
标签: nhibernate asp.net-mvc-3 structuremap