6

私は新しいプロジェクトを始めたばかりで、自然に多くの新しい技術を使用することを選択しました.

(Fluent) NHibernate、ASP.NET MVC 3 を使用しており、リポジトリ パターンを適用しようとしています。

ビジネス ロジックを別のプロジェクトに分割し、レポジトリをラップするサービスを定義して、NHibernate プロキシの代わりに POCO を返し、フロント エンドと DA ロジックの間の分離をさらに維持できるようにすることにしました。これにより、後で API と同じロジックを簡単に提供できるようになります (要件)。

私は、すべて IEntity を実装する NHibernate マップ エンティティの 1 つであるジェネリックIRepository<T>インターフェイスを使用することを選択しました (私のインターフェイスは実際にはマーカーのみです)。T

問題は、これが集約ルート パターンに反することであり、私は貧血ドメイン モデルの痛みを感じ始めています。

別のものにぶら下がっているオブジェクトを変更すると

  • ルート <- 変更
    • 子 <- 変更

私のサービスでは、次のことを行う必要があります。

public void AddNewChild(ChildDto child, rootId)
{
    var childEntity = Mapper.Map<ChildDto,ChildEntity>(child);
    var rootEntity = _rootrepository.FindById(rootId);
    rootEntity.Children.Add(childEntity);
    _childRepository.SaveOrUpdate(child);
    _rootRepository.SaveOrUpdate(root);
}

最初に子を保存しないと、NHibernate から例外が発生します。私の汎用リポジトリ (現在、1 つのサービスで 5 つ必要です) は正しい方法ではないように感じます。

 public Service(IRepository<ThingEntity> thingRepo, IRepository<RootEntity> rootRepo, IRepository<ChildEntity> childRepo, IRepository<CategoryEntity> catRepo, IRepository<ProductEntity> productRepo)

コードをより柔軟にするのではなく、より脆くしているように感じます。新しいテーブルを追加する場合、すべてのテストでコンストラクターを変更する必要があります (実装に DI を使用しているので、それほど悪くはありません) が、少し臭いようです。

この種のアーキテクチャを再構築する方法について誰かアドバイスはありますか?

リポジトリをより具体的にする必要がありますか? サービス抽象化レイヤーは行き過ぎですか?

編集:役立ついくつかの素晴らしい関連する質問があります:

4

2 に答える 2

2

アグリゲートがある場合、子のライフサイクルはルート オブジェクトによって制御されるため、リポジトリはアグリゲートの親 (ルート) とその子に対して同じです。

ルート オブジェクト タイプの「保存」メソッドは、さらに別のリポジトリに委任するのではなく、子レコードへの変更を永続化することも直接担当する必要があります。

さらに、「適切な」集計パターンでは、子レコードには独自の ID がありません (少なくとも 1 つは集計の外部に表示されます)。これには、いくつかの直接的な影響があります。

  1. 外部レコード/集計からそれらの子レコードへの外部キーは存在できません。
  2. ポイント 1. の結果として、ルート オブジェクトの状態を保存するたびに、データベース上の子レコードを削除して再作成できます。これにより、通常、優先順位の問題が発生した場合に永続化ロジックが容易になります。

注: 1. の逆のケースは当てはまりません。集約内の子レコードは、他のルート レコードへの外部キーを持つことができます。

于 2011-02-16T19:47:46.120 に答える