1. ホーム
  2. c#

[解決済み] リポジトリを集計ルートに還元する

2023-04-23 02:32:44

質問

私は現在、データベース内のほぼすべてのテーブルに対してリポジトリを持っていますが、それらを集約ルートのみに減らすことによって、DDD にさらに自分自身を合わせたいと考えています。

以下のテーブルがあると仮定します。 UserPhone . 各ユーザーは1つまたは複数の携帯電話を持っているかもしれません。 集約されたルートという概念がなければ、次のようなことを行うかもしれません。

//assuming I have the userId in session for example and I want to update a phone number
List<Phone> phones = PhoneRepository.GetPhoneNumberByUserId(userId);
phones[0].Number = “911”;
PhoneRepository.Update(phones[0]);

アグリゲートルートのコンセプトは、実際よりも紙の上で理解する方が簡単です。 Userに属さない電話番号を持つことはないので、PhoneRepositoryを廃止して、UserRepositoryに電話関連のメソッドを組み込むことは理にかなっているでしょうか。 答えがイエスであると仮定して、先のコードサンプルを書き換えてみます。

UserRepositoryに電話番号を返すメソッドを持つことは許されますか?それとも、常にユーザーへの参照を返し、そのユーザーを介してリレーションシップをたどり、電話番号を取得する必要がありますか。

List<Phone> phones = UserRepository.GetPhoneNumbers(userId);
// Or
User user = UserRepository.GetUserWithPhoneNumbers(userId); //this method will join to Phone

どの方法で電話を取得するかにかかわらず、それらのいずれかを変更したと仮定して、それらを更新するためにどのように行くのでしょうか? 私の限られた理解は、ルート下のオブジェクトはルートを通じて更新されるべきであり、それは以下の選択肢#1へと私を導くでしょう。 これはEntity Frameworkで完全に動作しますが、Entity Frameworkがグラフ内の変更されたオブジェクトのタブを維持しているにもかかわらず、コードを読むと私が実際に更新しているものがわからないので、これは非常に非記述的であると思われます。

UserRepository.Update(user);
// Or
UserRepository.UpdatePhone(phone);

最後に、いくつかのルックアップテーブルがあると仮定して、例えば CountryCodes , ColorsCodes , SomethingElseCodes . ドロップダウンを作成するため、または他の何らかの理由でそれらを使用することがあります。 これらは独立したリポジトリなのでしょうか? これらは、次のようなある種の論理的なグループ化/リポジトリにまとめることができますか? CodesRepository ? それとも、それはベストプラクティスに反していますか?

どのように解決するのですか?

リポジトリには、どのようなメソッドでも入れることができます :) あなたが言及した両方のケースで、それは電話リストが入力されたユーザーを返すことが理にかなっています。通常、ユーザーオブジェクトにはすべてのサブ情報 (たとえばすべての住所、電話番号) が完全に入力されているわけではなく、ユーザーオブジェクトに異なる種類の情報を入力させるための別のメソッドを用意することがあります。これはレイジーローディングと呼ばれます。

User GetUserDetailsWithPhones()
{
    // Populate User along with Phones
}

更新については、この場合、電話番号そのものではなく、ユーザが更新されます。ストレージモデルでは、電話番号を別のテーブルに格納することで、電話番号だけが更新されていると考えるかもしれませんが、DDDの観点で考えるとそうではありません。読みやすさに関しては

UserRepository.Update(user)

だけでは、何が更新されているのかがわかりません。また、更新されるものを示すフロントエンドのメソッド呼び出しの一部である可能性が高いです。

ルックアップテーブルのために、そして実際にそうでなくても、GenericRepositoryを持っていてそれを使うことは有用です。カスタムリポジトリはGenericRepositoryを継承することができます。

public class UserRepository : GenericRepository<User>
{
    IEnumerable<User> GetUserByCustomCriteria()
    {
    }

    User GetUserDetailsWithPhones()
    {
        // Populate User along with Phones
    }

    User GetUserDetailsWithAllSubInfo()
    {
        // Populate User along with all sub information e.g. phones, addresses etc.
    }
}

Generic Repository Entity Framework で検索すると、多くの素晴らしい実装が見つかります。それらのいずれかを使用するか、または独自のものを書いてください。