nhibernate / structuremap ObjectFactory.GetInstance ISession失败

时间:2011-03-30 14:25:37

标签: nhibernate session structuremap

我正在使用this method,对于我的asp.net mvc应用程序,它运行良好。但是当我在全局过滤器中使用它时:

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>();

    }        
}

这会导致'会话已关闭'错误。我做错了什么线索?

提前致谢!

1 个答案:

答案 0 :(得分:0)

好吧,我首先错过了有关全球过滤器的观点。

当然,这取决于你如何实例化过滤器。

  • 当您将filter定义为属性时,它会在控制器操作调用期间在运行时实例化,并且很容易注入当前可用的ISession实例。
  • 但是当您尝试将其添加到GlobalFilterCollection时 - 您必须(默认情况下)将其实例化为:filters.Add(new CustomActionFilter())。这意味着立即调用CustomActionFilter构造函数(在应用程序启动时)并尝试解析会话。您可以想象,对于您的MVC应用程序的所有请求,您不能使用相同的ISession。因此,您实施会话每请求模式。并且应该为每个请求注入新实例。

最简单的方法是将ISession分辨率(this.Session = ObjectFactory.GetInstance<ISession>();移至OnActionExecuting(...)方法。

更复杂的方法是创建自己的CustomFilterCollection类型并提供自己的过滤器注册基础架构。

更新:第一个提议的解决方案不适用。问题是过滤器在其属性中存储状态。有一些选择:

  • 使用过滤器作为属性,而不是GlobalFilterCollection元素。
  • 在过滤器本身内实现状态并发控制(即为全局过滤器的集合属性中的所有请求存储Sessions并以某种方式管理它们)。糟糕,臭臭接近imho,而且不可扩展。会话生存期管理不应属于过滤器。
  • 使用不同的过滤器注册系统(即推送您自己的IFilterProvider实现 - 以FluentFilters为例说明如何操作;或者只使用它。)

此外,最好将ActionFilterFilterAttribute分开。