Nhibernate session management strategy for web application with background-workers?

后端 未结 3 1368
灰色年华
灰色年华 2021-01-06 00:46

For a web application, it seems like a good way to handle the session is to use the setting managed_web

相关标签:
3条回答
  • 2021-01-06 01:22

    I solved it by creating my own session context class:

    public class HybridWebSessionContext : CurrentSessionContext
    {
        private const string _itemsKey = "HybridWebSessionContext";
        [ThreadStatic] private static ISession _threadSession;
    
        // This constructor should be kept, otherwise NHibernate will fail to create an instance of this class.
        public HybridWebSessionContext(ISessionFactoryImplementor factory)
        {
        }
    
        protected override ISession Session
        {
            get
            {
                var currentContext = ReflectiveHttpContext.HttpContextCurrentGetter();
                if (currentContext != null)
                {
                    var items = ReflectiveHttpContext.HttpContextItemsGetter(currentContext);
                    var session = items[_itemsKey] as ISession;
                    if (session != null)
                    {
                        return session;
                    }
                }
    
                return _threadSession;
            }
            set
            {
                var currentContext = ReflectiveHttpContext.HttpContextCurrentGetter();
                if (currentContext != null)
                {
                    var items = ReflectiveHttpContext.HttpContextItemsGetter(currentContext);
                    items[_itemsKey] = value;
                    return;
                }
    
                _threadSession = value;
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-06 01:35

    On my project, I wrote a little wrapper class around the CurrentSessionContext.
    Perhaps you can extend it to suit your needs.
    I think you just need to tweak the implementation of BindSessionToRequest and GetCurrentSession:

    public static class SessionManager
        {
            private static ISessionFactory _sessionFactory = null;
            private static ISessionFactory SessionFactory
            {
                get
                {
                    if (_sessionFactory == null)
                    {
                        //check whether we're in web context or win context, and create the session factory accordingly.
                        if (System.Web.HttpContext.Current != null)
                        {
                            if (_sessionFactory == null)
                            {
                                _sessionFactory = DAOBase.GetSessionFactory();
                            }
                        }
                        else
                        {
                            _sessionFactory = DAOBase.GetSessionFactoryForWin();
                        }
                    }
                    return _sessionFactory;
                }
            }
    
            public static void BindSessionToRequest()
            {
                ISession session = SessionManager.SessionFactory.OpenSession();
                NHibernate.Context.CurrentSessionContext.Bind(session);
            }
    
            public static bool CurrentSessionExists()
            {
                return NHibernate.Context.CurrentSessionContext.HasBind(SessionFactory);
            }
    
            public static void UnbindSession()
            {
                ISession session = NHibernate.Context.CurrentSessionContext.Unbind(SessionManager.SessionFactory);
                if (session != null && session.IsOpen)
                {
                    session.Close();
                }
            }
    
            public static ISession GetCurrentSession()
            {
                return SessionFactory.GetCurrentSession();
            }
        }
    
    0 讨论(0)
  • 2021-01-06 01:39

    I've found it simplest in this scenario to handle session creation myself using a DI library and 'hybrid' scope (in StructureMap, this is defined as InstanceScope.Hybrid). This will scope instances by HttpContext in an ASP.net app domain, and ThreadStatic in a normal app domain, allowing you to use the same approach in both.

    I'm sure other DI libraries offer a similar feature.

    0 讨论(0)
提交回复
热议问题