【发布时间】:2015-06-20 09:40:13
【问题描述】:
我现在陷入了 NHibernate,我正在尝试找出如何最好地正确设计我的存储库,同时正确管理 Session 的生命周期。
从我看到的示例来看,将 ISession 注入每个存储库中似乎很常见,如下所示:
public class SomeRepository : IRepository
{
private readonly ISession _session;
public SomeRepository(ISession session)
{
_session = session;
}
public IList<T> LoadSomeData()
{
return _session.Query<T>().Where(...).ToList();
}
}
所以这很好,但我可以看到一些会出现问题的情况:
1) 在应用的生命周期内可能没有 1 个会话。
2) 当访问 NHibernate 时,我们应该始终将我们的调用包装在一个事务中 - 如果事务出错,那么我们必须回滚事务并关闭会话。
在这两种情况下,存储库都将失效,因为它引用了一个关闭的会话。
我的特定应用程序是一个长时间运行的进程,它只会偶尔调用 NHibernate,所以我希望 Sessions 的周转率很高,而不是在应用程序的整个生命周期内保持 1 个 Session 处于打开状态。
因此,我想知道处理这种特殊情况的既定模式是什么?我看到了几个潜在的解决方案,但很难看出哪个是最佳做法:
1) 每次进程需要执行一些数据库工作时,重新构建存储库(并创建一个新会话)。
2) 使用 SessionFactory 注入存储库。然后存储库公开这个 SessionFactory。然后每个存储库的消费者在启动事务的同时打开一个新会话。
3) 创建一个 UnitOfWork 类,该类被注入存储库并负责管理会话生命周期和事务。每次调用 Repository 时,都会调用 UnitOfWork,它会创建一个全新的 Session 并在 Transaction 中执行调用。因此,存储库不知道会话/事务。
对我来说,3) 似乎是最好的解决方案,我在网上看到了一些这样的例子,但在所有例子中,他们只在 UnitOfWork 中创建了 1 个会话,并且如果交易他们不会重新创建它被回滚。
此外,3) 的限制是 UnitOfWork 与特定存储库相关联,因此您不能拥有调用不同存储库的事务。
希望这是有道理的,并希望得到任何指导。
谢谢
【问题讨论】:
标签: c# nhibernate unit-of-work