使用WebSessionContext / CurrentSessionContext延迟初始化ISession

时间:2010-12-16 23:12:36

标签: .net nhibernate httpcontext lazy-initialization isession

我正在使用NHibernate 3开始一个新项目,我正在尝试使用带有WebSessionContext的CurrentSessionContext API来管理我的ISession对象。

在以前的项目中,我总是自己管理,所以每当我需要一个ISession对象时,我会创建它并存储在HttpContext.Items集合中。非常简单,但使用本机解决方案(CurrentSessionContext)似乎是这个新项目的最佳选择。

当我管理对象时,我能够对它进行延迟初始化,这意味着我只在需要时打开一个Session而不是在每个请求中打开,因为我可能不需要它,并且会浪费资源/时间一直打开它。

使用CurrentSessionContext API有一种简单的方法吗?

以下是我在负责此操作的HttpModule中使用的代码:


public class ContextualSessionModule : IHttpModule
{

    public void Init(HttpApplication context)
    {
        context.BeginRequest += context_BeginRequest;
        context.EndRequest += context_EndRequest;
    }

    public void Dispose()
    {
    }

    private static void context_BeginRequest(object sender, EventArgs e)
    {
        var application = (HttpApplication)sender;
        var context = application.Context;

        BindSession(context);
    }

    private static void BindSession(HttpContext context)
    {
        // Create a new session (it's the beginning of the request)
        var session = SessionBuilderFactory.CurrentSessionFactory.OpenSession();

        // Tell NH session context to use it
        CurrentSessionContext.Bind(session);
    }

    private static void context_EndRequest(object sender, EventArgs e)
    {
        var application = (HttpApplication)sender;
        var context = application.Context;

        UnbindSession(context);
    }

    private static void UnbindSession(HttpContext context)
    {
        // Get the default NH session factory
        var factory = SessionBuilderFactory.CurrentSessionFactory;

        // Give it to NH so it can pull the right session
        var session = CurrentSessionContext.Unbind(factory);

        if (session == null) return;
        session.Flush();
        session.Close();
    }
}

修改

迭戈几乎把它钉了下来,但我想到了更多关于这一点,我想起了我自己实现控制的主要原因:交易。

我是Onion Architecture家伙,所以我的域对象(知道何时开始交易的人)无权访问基础架构,因此无法启动交易。

为了解决这个问题,我使用延迟初始化并在打开Session时始终启动事务。提交在请求结束且没有捕获异常时发生。 除此之外,Ayende建议总是使用交易,即使在查询时也是如此。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

虽然不是直接回答你的问题,但我认为:为什么?

会话是一个轻量级对象。如果你不使用它,它只是初始化一些内部结构,但它不会打开数据库连接或任何东西。

为了节省一点时间/内存,有一些例子(仅谷歌)可以避免打开静态对象的会话。除此之外,它可能不值得,除非你的分析表明它会伤害你的表现。

更新:有关交易需求,请查看uNhAddIns中的CpBT实现。