nhibernate/structuremap ObjectFactory.GetInstance ISession失败
我正在使用asp.NETMVC应用程序,它工作得很好。但当我在全局过滤器中使用它时:nhibernate/structuremap ObjectFactory.GetInstance ISession失败,nhibernate,session,structuremap,Nhibernate,Session,Structuremap,我正在使用asp.NETMVC应用程序,它工作得很好。但当我在全局过滤器中使用它时: public class CustomActionFilter: ActionFilterAttribute { public ISession Session { get; set; } public CustomActionFilter() { this.Session = ObjectFactory.GetInstance<ISession>();
public class CustomActionFilter: ActionFilterAttribute
{
public ISession Session { get; set; }
public CustomActionFilter()
{
this.Session = ObjectFactory.GetInstance<ISession>();
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//call ISession.CreateQuery(...); query.UniqueResult<SomeObject>();
}
}
公共类CustomActionFilter:ActionFilterAttribute
{
公共ISession会话{get;set;}
公共CustomActionFilter()
{
this.Session=ObjectFactory.GetInstance();
}
公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
{
//调用ISession.CreateQuery(…);query.UniqueResult();
}
}
这将导致“会话关闭”错误。我做错了什么,有什么线索吗
提前谢谢 首先,我忽略了关于全局过滤器的一点 当然,这取决于您如何实例化过滤器
- 当您将筛选器定义为属性时,它将在运行时控制器操作调用期间实例化,并轻松注入当前可用的
实例ISession
- 但是,当您尝试将其添加到
时,您必须(默认情况下)像这样实例化它:GlobalFilterCollection
。这意味着filters.add(new CustomActionFilter())
构造函数将立即被调用(在应用程序启动时),并尝试解析会话。正如您所想象的,您不能对MVC应用程序的所有请求使用相同的CustomActionFilter
。因此,您可以实现每个请求的会话模式。并且应该为每个请求注入新实例ISession
this.Session=ObjectFactory.GetInstance();
移动到OnActionExecuting(…)
方法
更复杂的方法是创建自己的CustomFilterCollection
类型并提供自己的过滤器注册基础结构
更新:第一个建议的解决方案不适用。问题是筛选器在其属性中存储状态。尽管有以下选项:
- 将过滤器用作属性,而不是
元素GlobalFilterCollection
- 在筛选器本身内部实现状态并发控制(即,在全局筛选器的集合属性中为所有请求存储
,并以某种方式对其进行管理)。糟糕、难闻的方法imho,且不可扩展。会话生存期管理不应属于筛选器会话
- 使用不同的过滤器注册系统(即,滚动您自己的
——以如何执行为例;或者仅使用它)IFilterProvider
另外,最好将
ActionFilter
s与filteratribute
s分离。请您,plz,为ISession
,以及与NHibernate会话管理相关的所有其他内容,提供多一点StructureMap注册代码。如果在同一时间有两个请求使用该筛选器,是否会有进一步的复杂性同一时间?其中一个可能在第二个请求完成处理之前关闭会话。是的,看起来你是对的。此外,“其中一个可能在第二个请求完成处理之前关闭会话”
完全是错误的-两个不同的请求不应该使用同一会话(除了某些特定的“DB对话”)场景)。您的操作筛选器属性存储状态(ISession)-这就是问题所在。您可以将此类筛选器用作属性,也可以将实际筛选器与属性解耦(在MVC3中,筛选器不再需要是属性)。最好的选择是使用类似的方法。这样,您可以只定义筛选器的类型,但实际筛选器将根据每个请求进行实例化。