3

私は自分のドメイン モデルを可能な限り持続性を考慮しないように書こうとしています。私が現在行っている唯一のことはvirtual、NHibernate が遅延読み込みのためにそれを必要とするため、すべてのプロパティとメソッドをマークすることです。

私のドメイン モデル アセンブリでは、いくつかのリポジトリ インターフェイスを定義します。

public interface IRepository<TEntity> where TEntity : EntityBase {
    TEntity Get(int id);
    /* ... */
}
public interface IProductRepository : IRepository<Product> { ... }

次に、データ アセンブリがあります。これはNHibernateを参照し、その存在を知っています。これは、これらのリポジトリ インターフェイスを実装するアセンブリです。

public abstract class Repository<TEntity> : IRepository<TEntity> {
    public TEntity Get(ind id) { ... }
    /* ... */
}
public class ProductRepository : Repository<Product>, IProductRepository {
    /* ... */
}

等々。

ここで、リポジトリにトランザクション機能を実装したいと考えました。そのためBeginTransactionに、IRepository インターフェイスにメソッドを追加します。ただし、NHibernate.ITransactionドメイン モデルの永続性を無視し、ドメイン モデル アセンブリから NHibernate のアセンブリを強制的に参照したくないため、戻り値の型を として定義することはできません。

あなたならどうしますか?

インターフェースにa void BeginTransaction()、 a void Commit()、および aメソッドを単純に実装し、リポジトリの実装でオブジェクトを内部的に管理しますか?void RollBack()ITransaction

それとも、リポジトリのメソッドを使用する代わりに、オブジェクトを公開しITransactionて、クライアントがトランザクションを直接管理できるようにする方法を見つけますか?

ありがとう!

4

2 に答える 2

2

トランザクションをサポートする一般的なリポジトリを含め、あなたが話しているすべてをすでに実装しているSharp Architectureを見ることができます。そこでの解決策は、トランザクションをカプセル化する DbContext プロパティが IRepository にあることです (実際にはインターフェイスです)。これは、あなたが説明した最初のオプションです (NHibernate を非表示にするカスタム トランザクション インターフェイス)。そして、それはうまく機能します。

完全なフレームワークを使用するつもりであるかどうかに関係なく、S#arp コードを再利用することもできると思います。

于 2009-09-04T18:34:52.880 に答える
0

IMO トランザクションは常にビジネス ロジックで開始および終了する必要があります。つまり、トランザクションはリポジトリ レイヤーではなくサービス レイヤーで開始する必要があり、リポジトリはそれ自体をトランザクションに登録する必要があります。理想的には、これは暗黙的に行われます。

NH を使用している場合、サービスとリポジトリが同じ「セッション」を共有している場合 (共有する必要があります)、サービス層で「BeginTransaction」を呼び出し、必要に応じてコミットまたはロールバックできます。

たとえば、これがサービスのメソッドであると想像してください。

  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 を使用して現在のセッションを取得することで解決できます...

于 2009-09-03T13:57:01.237 に答える