0

我正在设置我的 MVC 项目,以便我ISession在 PerWebRequest 的基础上解决我的问题。

这是我到目前为止所拥有的:

在我的 Castle Windsor 设置中,我ISession使用工厂方法注册了我的:

Component.For<ISession>().UsingFactoryMethod(ctx => MsSql2008SessionFactory.OpenSession()).LifestylePerWebRequest()

在我的每次请求开始时,我都将Global.asax Application_Start()我的绑定ISession到 NHibernate :CurrentSessionContext

BeginRequest += delegate{
            CurrentSessionContext.Bind(
                     MsSql2008SessionFactory.OpenSession());
                       };

EndRequest += delegate{
             var session = MsSql2008SessionFactory
                             .SessionFactory
                               .GetCurrentSession();
              if (session != null)
              {
                session.Dispose();
              }
             CurrentSessionContext
                     .Unbind(MsSql2008SessionFactory
                         .SessionFactory);
        };

我第一次向页面发出请求时一切正常。第二次向页面发出请求时,我得到一个异常说明:

会话关闭!对象名称:'ISession'。

我做错了什么?

4

2 回答 2

2

答案很简单。

我注入的存储库ISession有一种Singleton生活方式。

这意味着ISession在第一个请求中注入的 也被用于后续请求(因为我的存储库类仅在应用程序启动时创建),因此已经被释放。

于 2012-05-12T12:35:26.850 回答
2

这就是我做事的方式可能对你有用。我使用 Fluent Nhibernate 以防某些配置无法运行。

public interface INHibernateSessionFactoryHelper
{
    ISessionFactory CreateSessionFactory();
}


public class NhibernateSessionFactoryHelper
{
    private static readonly string ConnectionString =
        ConfigurationManager.ConnectionStrings["SqlConnectionString"].ToString();

    public static ISessionFactory CreateSessionFactory()
    {
        return Fluently.Configure()
            .ProxyFactoryFactory("NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate")
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<EntityMap>())
            .Database(
                MsSqlConfiguration.MsSql2008.ConnectionString(ConnectionString).AdoNetBatchSize(1000))
            .Cache(
                c =>
                c.ProviderClass<SysCacheProvider>().UseSecondLevelCache().UseQueryCache().UseMinimalPuts())
            .ExposeConfiguration(c => c.SetProperty(Environment.GenerateStatistics, "true")
                                          .SetProperty(Environment.SessionFactoryName, "My Session Factory")
                                          .SetProperty(Environment.CurrentSessionContextClass, "web"))
            .Diagnostics(d => d.Enable().OutputToFile(@"c:\temp\diags.txt"))
            .BuildSessionFactory();
    }
}

然后我的 Windsor 安装程序看起来像这样

public class NHibernateInstaller:IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
            Component.For<ISessionFactory>().Instance(NhibernateSessionFactoryHelper.CreateSessionFactory()));
        container.Register(Component.For<ISessionManager>().ImplementedBy<SessionManager>().LifestylePerWebRequest());
    }
}

我省略了我使用的 SessionManager 的代码。让我知道你是否愿意

UPDTAE:这是我用于管理会话和事务的代码(我发现这些代码分散在 Internet 上,但没有太多修改就可以很好地工作。ISessionManager 按照我之前的示例连接起来并注入到我的服务的构造函数中.

public interface ISessionManager : IDisposable
{
    ISession Session { get; set; }
    ISession GetSession();
}

public class SessionManager : ISessionManager
{
    private readonly ISessionFactory _sessionFactory;
    private TransactionScope _scope;
    public SessionManager(ISessionFactory sessionFactory)
    {
        _sessionFactory = sessionFactory;
    }

    #region ISessionManager Members

    public ISession Session { get; set; }

    public ISession GetSession()
    {
        if (Session == null)
        {
            Session = _sessionFactory.OpenSession();
            if (!CurrentSessionContext.HasBind(_sessionFactory))
            {
                _scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions {IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted});
                Session.BeginTransaction(IsolationLevel.ReadCommitted);
                CurrentSessionContext.Bind(Session);
            }
        }

        Session = _sessionFactory.GetCurrentSession();
        Session.FlushMode = FlushMode.Never;
        return Session;
    }


    public void Dispose()
    {
        if (CurrentSessionContext.HasBind(_sessionFactory))
        {
            CurrentSessionContext.Unbind(_sessionFactory);
        }
        try
        {
            Session.Transaction.Commit();
            _scope.Complete();
            _scope.Dispose();
            Session.Flush();
        }
        catch (Exception)
        {
            if (Session.Transaction != null && Session.Transaction.IsActive)
            {
                Session.Transaction.Rollback();
            }
            throw;
        }
        finally
        {
            Session.Close();
            Session.Dispose();
        }
    }

    #endregion
}

示例构造函数:

private readonly ISessionManager _sessionManager;
private readonly ISession _session;
 public UserService(ISessionManager sessionManager)
    {

        _sessionManager = sessionManager;
        _session = sessionManager.GetSession();

     }
于 2012-05-06T03:13:44.837 回答