NHibernateはITransactionと純粋なドメインモデル
-
21-09-2019 - |
質問
私は、永続性の無知をできるだけ私のドメインモデルを記述しようとしています。 NHibernateのは、遅延ロードのためにそれを必要とする私が今やっている唯一のことは、すべてのプロパティとメソッドvirtual
マーキングされます。
アセンブリ私のドメインモデルではの私はいくつかのリポジトリのインターフェイスを定義します:
public interface IRepository<TEntity> where TEntity : EntityBase {
TEntity Get(int id);
/* ... */
}
public interface IProductRepository : IRepository<Product> { ... }
それから私は、のデータはアセンブリを持っています。 NHibernateはを参照します。この1は、それがその存在を知っています。これはアセンブリである実装ものリポジトリインターフェース
public abstract class Repository<TEntity> : IRepository<TEntity> {
public TEntity Get(ind id) { ... }
/* ... */
}
public class ProductRepository : Repository<Product>, IProductRepository {
/* ... */
}
のように。
今、私はを私のリポジトリへのトランザクション機能を実装したかったです。そうするために、私は私のIRepositoryインターフェイス上BeginTransaction
メソッドを追加します。私はアセンブリ私のドメインモデルからのNHibernateのアセンブリを参照することを余儀なくされ永続性の無知なドメインモデルを維持し、しないようにしたいので、私は、NHibernate.ITransaction
とその戻り値の型を定義することはできません。
あなたは何をしますか?
でしょうあなたは、単にvoid BeginTransaction()
、void Commit()
、およびインターフェイス上のvoid RollBack()
メソッドを実装し、聞かせてのリポジトリの実装は、内部のITransaction
オブジェクトを管理する?
それともへの道を見つけるだろうの ITransaction
オブジェクトのクライアントではなく、リポジトリのメソッドを使用するのでは、それを直接トランザクションを管理できるようにするためにを公開する?
ありがとうございます。
解決
あなたはすでにジェネリックを含め、あなたがについて話すべてを、実施しているシャープアーキテクチャのを見てみることができます取引をサポートしたリポジトリ。解決策はIRepositoryは(それが実際にインタフェースです)トランザクションをカプセル化するDbContext性質を持っていることがあります。 これは(NHibernateのを隠してカスタム取引インタフェース)を記述することを選択肢の最初のものです。そして、それはうまく動作します。
私はあなたが関係なく、あなたが完全なフレームワークを使用する場合でも、再利用のS#arpコマンドのコードことができますね。
他のヒント
IMO取引は常に起動して、ビジネスロジックで終了する必要があり、換言すれば、トランザクションはサービス層ではないリポジトリ層を開始する必要があり、リポジトリは、トランザクション内のそれの自己を参加させる必要があり、理想的にはこれが暗黙的に行われることになる。
今、あなたはその後、NHを使用している場合は、あなたのサービスとリポジトリが同じ「セッション」を共有している場合、必要に応じて(彼らは必要があります)、あなたはサービス層に「でBeginTransaction」を呼び出してコミットまたはロールバックすることができます:
Egは、本サービス上のメソッドを想像します:
public void RegisterCustomer(Customer customer) { try { using(var transaction = _session.BeginTransaction()) { _customerRepository.Save(customer); _customerSurveyRepository.Save(customerSurvey); // DO What ever else you want... transaction.Commit(); } } catch (Exception exn) { throw new AMException(FAILED_REGISTRATION, exn); } }
リポジトリがコンストラクタに注入することによって、または...
現在のセッションを取得するためのSessionFactoryを使用することによって解決することができ、同じセッションへの参照を取得する方法