私は以下の実装を持っており、NHibernateをセッションとトランザクションに正しく使用するかどうかのフィードバックをしたいと思います。ここでNHibernateの作業単位パターンとNinjectの正しい使用
Bind<IUnitOfWork>().To<UnitOfWork>().InTransientScope();
Bind<ISessionFactory>().ToProvider<NHibernateSessionFactoryProvider>().InSingletonScope();
Bind<IRepository>().To<Repository>().InTransientScope();
を結合
public interface IUnitOfWork : IDisposable
{
ISession CurrentSession { get; }
void Commit();
void Rollback();
}
public class UnitOfWork : IUnitOfWork
{
private readonly ISessionFactory _sessionFactory;
private readonly ITransaction _transaction;
public UnitOfWork(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
CurrentSession = _sessionFactory.OpenSession();
_transaction = CurrentSession.BeginTransaction();
}
public ISession CurrentSession { get; private set; }
public void Dispose()
{
CurrentSession.Close();
CurrentSession = null;
}
public void Commit()
{
_transaction.Commit();
}
public void Rollback()
{
if (_transaction.IsActive) _transaction.Rollback();
}
}
Ninjectは使い方の例です:
私の以前の実装ではpublic class Repository : IRepository
{
private readonly ISessionFactory _sessionFactory;
public Repository(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
}
public void Add(IObj obj)
{
using (var unitOfWork = new UnitOfWork(_sessionFactory))
{
unitOfWork.CurrentSession.Save(obj);
unitOfWork.Commit();
}
}
}
私はそう
public Repository(IUnitOfWork unitOfWork)
{...
のように私のリポジトリコンストラクタにIUnitOfWorkを注入します
しかし、Dispose()メソッドは実行されず、この例外をスローするために後続の呼び出しが発生します。「破棄されたオブジェクトにアクセスできません。オブジェクト名: 'AdoTransaction'。 "
あなたの最終的な決定は何でしたかわかりませんが、それをしないでください! :)真面目に、NHibernateはすでにかなりの抽象化とUoWパターンを追加しています。ちょうど箱からすぐにNHibernateを使用し、あなたのコードをシンプルに保つ。あなたは本当にデバッグするためにさらに抽象化したいですか? –