Ensure NHibernate SessionFactory is only created once

前端 未结 2 2100
忘了有多久
忘了有多久 2020-12-03 03:43

I have written an NHibernateSessionFactory class which holds a static Nhibernate ISessionFactory. This is used to make sure we only have one session factory, and the first t

相关标签:
2条回答
  • 2020-12-03 04:10

    I solved this using a Mutex when creating the SessionFactory. Does this look reasonable:

    public class NhibernateSessionFactory : INhibernateSessionFactory
    {
        private static ISessionFactory _sessionFactory;
        private static Mutex _mutex = new Mutex();  // <-- Added
    
        public ISession OpenSession()
        {
            if (_sessionFactory == null)
            {
                _mutex.WaitOne();              // <-- Added
                if (_sessionFactory == null)   // <-- Added
                {                              // <-- Added
                    var cfg = Fluently.Configure().
                        Database(SQLiteConfiguration.Standard.ShowSql().UsingFile("Foo.db")).
                        Mappings(m => m.FluentMappings.AddFromAssemblyOf<MappingsPersistenceModel>());
                    _sessionFactory = cfg.BuildSessionFactory();
                    BuildSchema(cfg);
                }                              // <-- Added
                _mutex.ReleaseMutex();         // <-- Added
    
            }
            return _sessionFactory.OpenSession();
        }
    
        private static void BuildSchema(FluentConfiguration configuration)
        {
            var sessionSource = new SessionSource(configuration);
            var session = sessionSource.CreateSession();
            sessionSource.BuildSchema(session);            
        }
    }
    

    Seems to work like a charm. But should I use lock instead?

    0 讨论(0)
  • 2020-12-03 04:23

    The sessionFactory must be a thread-safe singleton.

    A common pattern in Java is to build the sessionFactory in a static initializer. See HibernateUtil. You can do the same in C#.

    There are other patterns to implement singleton, including the usage of lock or synchronized sections. Here is slight variant that should solve your problem if I understood it correctly.

    static readonly object factorylock = new object();
    
    public ISession OpenSession()
    {
        lock (factorylock)
        {
           if (_sessionFactory == null)
           {
                var cfg = Fluently.Configure().
                   Database(SQLiteConfiguration.Standard.ShowSql().UsingFile("Foo.db")).
                   Mappings(m => m.FluentMappings.AddFromAssemblyOf<MappingsPersistenceModel>());
                _sessionFactory = cfg.BuildSessionFactory();
                BuildSchema(cfg);
            }
        }
        return _sessionFactory.OpenSession();
    }
    
    0 讨论(0)
提交回复
热议问题