私のリポジトリはUnitOfWork
モデルで動作します。検索や永続のいずれの操作も、IDisposable
UnitOfWork
トークンオブジェクトの範囲内で実行する必要があります。トークンオブジェクトの背後には、要求された作業を実行するSession
が関連付けられています。だから、基本的なパターンは次のとおりです。NHibernateセッションに切断オブジェクトをアタッチする。ベストプラクティス?
using (var uow = repo.BeginUnitOfWork())
{
try
{
//DB operations here; all repo methods require passing in uow.
...
repo.CommitUnitOfWork(uow);
}
catch(Exception)
{
repo.RollbackUnitOfWork(uow);
throw;
}
}
私も毎回すべて、この足場を実装する必要性を軽減、あなたはこの枠組みの中で実行されるラムダまたはデリゲートを指定することができ、いくつかのラッパー・メソッドを実装しました。
私が抱えている問題は、このモデルを使用すると、コードがUnitOfWork
内のNHUtil.Initialize()
を使用して、ユーザーが必要としていることを「知って」いることがわかります。 UOWが使用ブロックの最後に配置されると、PersistentBags
に関連付けられたセッションは閉じられ、評価されません。前向きなものをすべて積み重ねることは必ずしも実現可能ではないし、遅延ロードORMの目的を破るようなものであるので、私はAttach()
メソッドを実装しています。
ここに質問があります。組み込みのISession.Attach()
メソッドがない場合は、オブジェクトを新しいセッションに関連付けることを推奨している3つのメソッドがあります。仕事を終わらせるベストプラクティスはどれですか?
A:
if(!Session.Contains(domainObject))
Session.Update(domainObject);
B:
Session.Merge(domainObject);
C:
Session.Lock(domainObject, LockMode.None);
十分に公正です。私は現在のレポアーキテクチャに縛られていません。基本的なパターンは、UnitOfWorkオブジェクトがIDisposableを実装するフライウェイトトークンであり、セッションがクリーンアップされるようにリポジトリにコールバックすることです。現在、Dispose()はユーザコードによって呼び出されなければならず、そうでなければDBはオープンのままなので、使用パターンは最も論理的です。 IDisposableの実装をより堅牢にすることができますので、オブジェクトがGCedされているときに必要に応じて呼び出されるか、他のパターンを見ることができます。あなたの提案? – KeithS
実際には、「よりロバストな」パートをキャンセルしてください。リポジトリ内のUOWへの参照があるので、明示的に配置しない限り、リポジトリが破棄されるまで(プログラムの有効期間中はIoCコンテナを介してメモリに保持されます) – KeithS
UOWをリポジトリのコンストラクタに渡す必要があります。個人的に私は、それをラップするのではなく、直接セッションを使用します。セッションを廃棄することは重要ですが、多くの場合、それを使用ブロックにラップするのは実際的ではなく、適切な時期にDisposeを呼び出す必要があります。 –