3

これらの質問をいくつか見てきましたが、常に私の考えと一致していないようです。これは、集計 - 集計ルート - 実体 - 値オブジェクト間の関係を私のずさんな理解によるものだと思います。

完成したソリューションは、すべて (すべてのロジック) が最終的にリポジトリ内にあるように見えるため、私には DTO のように見えます。おそらく私は EF のチュートリアルを見すぎていたのでしょう。

リポジトリの最初のバージョンを持つ非常に単純なクラスがあると仮定します (1 人しか処理しないことは無視しましょう)。

class Person 
{
    int Age;
    void MakeOlder() { Age++; }
}
interface IPersonRepository
{
    Person GetAPerson();
}

今、私が UI からやりたいこと (たとえば、ボタンを押したとき) は、次のことではありません

person.MakeOlder();
_repo.Save(person);

しかし、おそらくただ:

person.MakeOlder();

私にとって、「MakeOlder」のアクションは、保存をトリガーするものです。しかしもちろん、これには個人のレポへの参照が必要です。私が考えることができる唯一のオプションは次のとおりです。

_repo.MakePersonOlder(person);

(ひどいようです。)

person.MakeOlder(_repo);

(私が今見ているUI povからの利益はありません)

class Person : IMyEntityBaseType { ...
    void MakeOlder() { 
        Age++; 
        EntityDataWasChangedNowIWantToBeSaved(); 
    }
}

または、これのいくつかの変形。イベント、AOPなど。保存を行う必要があることを何らかの方法で通知またはキャプチャします。

また、DDD に対する私の見解を、イベント ソーシングや類似の概念と混同している可能性もあります。

SavePersonUIコードの呼び出しが汚いと思うのは完全に間違っていますか?

「正しい」ことは何ですか?

4

2 に答える 2

4

リポジトリを Person に渡すべきではありません。そのモデルでは、すべてのメソッドにリポジトリを渡す必要があります。通常、EF やその他の ORM を使用している場合は、unit of workという概念が組み込まれています。作業単位は、定義された対話内で変更されたすべてのオブジェクトを追跡します。作業単位をコミットすると、その中のすべての変更がコミットされます。コードは次のようになります。

person.MakeOlder();
_unitOfWork.Commit();

このアプローチは、複数のエンティティに変更がある場合に使用できます。ORM は変更を追跡するため、作業単位の一部である各オブジェクトを明示的に保存する必要はありません。

あなたの懸念にも対処するより良いオプションは、ユースケースをアプリケーションサービスでカプセル化することです。アプリケーション サービスには、次のようなメソッドがあります。

public void MakeOlder(int personId)
{
   var person = this.personRepository.Get(personId);
   person.MakeOlder();
   this.unitOfWork.Commit();
}

UI は、ドメイン オブジェクトを直接呼び出す代わりに、アプリケーション サービスを呼び出します。

于 2013-05-21T17:23:43.427 に答える