我试图用NHibernate实现UnitOfWork和Repository模式。我正在寻找在工作单元实例和存储库实例之间共享会话的最佳方法。
最明显的方式是在ThreadStatic
类中引入UnitOfWork
属性
public class UnitOfWork : IUnitOfWork
{
public static UnitOfWork Current
{
get { return _current; }
set { _current = value; }
}
[ThreadStatic]
private static UnitOfWork _current;
public ISession Session { get; private set; }
//other code
}
然后在Repository
课程中:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected ISession Session { get { return UnitOfWork.Current.Session; } }
//other code
}
但是我并不喜欢上面列出的实现,并决定找到另一种方法来做同样的事情。
所以我以第二种方式来 :
public interface ICurrentSessionProvider : IDisposable
{
ISession CurrentSession { get; }
ISession OpenSession();
void ReleaseSession();
}
public class CurrentSessionProvider : ICurrentSessionProvider
{
private readonly ISessionFactory _sessionFactory;
public CurrentSessionProvider(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
}
public ISession OpenSession()
{
var session = _sessionFactory.OpenSession();
CurrentSessionContext.Bind(session);
return session;
}
public void Dispose()
{
CurrentSessionContext.Unbind(_sessionFactory);
}
public ISession CurrentSession
{
get
{
if (!CurrentSessionContext.HasBind(_sessionFactory))
{
OnContextualSessionIsNotFound();
}
var contextualSession = _sessionFactory.GetCurrentSession();
if (contextualSession == null)
{
OnContextualSessionIsNotFound();
}
return contextualSession;
}
}
private static void OnContextualSessionIsNotFound()
{
throw new InvalidOperationException("Session is not opened!");
}
}
其中ISessionFactory
是由autofac解析的单身,CurrentSessionContext
是CallSessionContext
。
然后我在ICurrentSessionProvider
和UnitOfWork
类的构造函数中注入Repository
并使用CurrentSession
属性来共享会话。
这两种方法似乎都运转正常。所以我想知道有没有其他方法来实现这个?在工作单元和存储库之间共享会话的最佳实践是什么?
答案 0 :(得分:0)
这样做的最佳方式是利用NHibernate已经为此提供的便利。 请查看以下文档中的“2.3。上下文会话”部分:http://nhibernate.info/doc/nh/en/#architecture-current-session
基本上,你需要:
这样做的好处是,您的会话处理策略将与大多数NHibernate项目应该如何完成兼容,并且它不依赖于您想要访问当前会话的地方除了ISessionFactory之外的任何内容。
忘记提及:您当然可以根据您在问题中列出的代码实现自己的ICurrentSessionContext。