确保NHibernate SessionFactory仅创建一次

sti*_*k81 14 c# nhibernate sessionfactory fluent-nhibernate

我编写了一个NHibernateSessionFactory类,它包含一个静态的Nhibernate ISessionFactory.这用于确保我们只有一个会话工厂,并且第一次调用OpenSession()我创建了一个实际的SessionFactory - 下次我使用相同的并打开一个会话.代码如下所示:

public class NhibernateSessionFactory : INhibernateSessionFactory
{
    private static ISessionFactory _sessionFactory;

    public ISession OpenSession()
    {
        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();
    }

    private static void BuildSchema(FluentConfiguration configuration)
    {
        var sessionSource = new SessionSource(configuration);
        var session = sessionSource.CreateSession();
        sessionSource.BuildSchema(session);            
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我有一个问题.我的应用程序分为客户端和服务器.Nhibernate的东西在服务器端.在启动时,我的客户端和服务器都希望通过一些将使用NhibernateSessionFactory的服务来访问数据库.结果是在请求来自客户端之前是否创建了_sessionFactory的竞争条件.如果不是它会失败..

我想我需要在NhibernateSessionFactory中使用某种排队或等待机制,但我不知道该怎么做.以前有人遇到过同样的问题吗?什么是最好的解决方案?

ewe*_*nli 19

sessionFactory必须是线程安全的单.

Java中的一个常见模式是sessionFactory在静态初始化器中构建.请参阅HibernateUtil.您可以在C#中执行相同的操作.

还有其他模式可以实现单例,包括锁定或同步部分的使用.这是一个轻微的变种,如果我理解正确,应解决您的问题.

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();
}
Run Code Online (Sandbox Code Playgroud)