6

私はエンティティフレームワークでasp.netmvcを使用しており、DDDの学習を開始しています。私は調査を含むプロジェクトに取り組んでいます。これが私のドメインモデルです:

public class Survey
{
    public int? SurveyID { get; set; }
    public string Name { get; set; }
    public decimal MinAcceptanceScore { get; set; }
    public int UserFailsCount { get; set; }

    public IEnumerable<SurveyQuestion> Questions { get; set; }
    public IEnumerable<Prize> Prizes { get; set; }
    public IEnumerable<SurveyAttempt> UserAttempts { get; set; }
}

ビューごとに調査のさまざまな部分が必要なので、さまざまなViewModelを作成しました。

    public class ShortSurveyViewModel
    {
        public int? SurveyID { get; set; }
        public string Name { get; set; }
        public int UserFailsCount { get; set; }
        public IEnumerable<SurveyAttempt> UserAttempts { get; set; }
    }

    public class ShortSurveyWithPrizesViewModel
    {
        public int? SurveyID { get; set; }
        public string Name { get; set; }
        public int UserFailsCount { get; set; }
        public IEnumerable<SurveyAttempt> UserAttempts { get; set; }
        public IEnumerable<Prize> Prizes { get; set; }
    }

    public class SurveyEditViewModel
    {
        public int? SurveyID { get; set; }
        public string Name { get; set; }
        public decimal MinAcceptanceScore { get; set; }
        public int UserFailsCount { get; set; }

        public IEnumerable<SurveyQuestion> Questions { get; set; }
        public IEnumerable<Prize> Prizes { get; set; }
    }

適切なビューモデルに必要な情報を調査リポジトリに取得させたい場合、アーキテクチャを構築するための最良の方法は何でしょうか。

私が見るさまざまな幻想:

  1. リポジトリはIQueryableをSurveyServiceに返し、サービスは適切なビューモデルを返すことができますが、ビューモデルはサービスレイヤーではなくUIで作成する必要があると思うので、これを行うのは正しいと思います。

  2. ドメインレイヤーに3つの適切なクラスを作成します。ただし、ドメインは表現に依存するようになり、新しいビューごとに新しいドメインクラスを作成する必要があります。

  3. 完全なドメインオブジェクトを取得し、特定のビューに必要なプロパティのみをマップします。私の例では、質問は1つの表現でのみ必要であり、大量のコレクションになる可能性があるため、これは適切ではありません。

4

2 に答える 2

9

ドメイン駆動設計:

  • 集約ルートを返すリポジトリが必要です-あなたの場合Survey、親なしでは存在できないすべての関係Survey
  • このリポジトリは常にSurveyクラス全体をロードし、要件に応じて一部の関係のみをロードします(本当に独断的なDDDは常に集約全体をロードしますが、ステートレスWebには適していません)。
  • アプリケーション層(コントローラー)は、リポジトリにSurvey選択されたリレーションを要求し、ビューモデルを塗りつぶします。

タマネギのアーキテクチャ:

  • 公開するリポジトリを作成しますIQueryable<Survey>-さらに悪いことに、CRUDインターフェイスで汎用リポジトリを使用します
  • リポジトリを呼び出すサービスを作成し、Linq-to-entitiesプロジェクションをDTOに構築して、アプリケーション層(コントローラー)に返します。
  • それで?これらのDTOを直接使用することも、UI関連の属性などを使用してビューモデルとして使用される別のオブジェクトのセットを使用することもできます。明らかに何か問題があります...

シンプルなアーキテクチャ:

  • コントローラに直接注入さIDbSet<Survey>れたものをリポジトリとして使用します
  • ビューモデルを塗りつぶすために、コントローラーで直接Linq-to-entitiesプロジェクションを作成します

最善の方法はありません。それは常にあなたの目標とあなたの期待についてです。小さなアプリケーションの場合、問題なくシンプルなアーキテクチャで動作できます。

ドメイン駆動設計はより複雑です。DDDの主な概念は、ドメインエンティティ、値オブジェクト、およびそれらの構成です。ドメインエンティティは、データとそれらのデータに対して実行されるロジックをカプセル化します。DDDは部分的なデータまたはDTOでは機能しません-ドメインエンティティに間違ったロジックがない場合(貧血モデルと呼ばれます)。DDDのサービスは、アプリケーション層とリポジトリの間の仲介役ではありません。これは、単一のドメインエンティティに関連しないビジネスロジックを処理するために使用されます(したがって、ドメインエンティティにカプセル化することはできません)。リポジトリは、ストレージからアグリゲートをマテリアライズし、ストレージに永続化するために必要なインフラストラクチャコードです。アプリケーションロジック(コントローラー)は、ドメインエンティティ、サービス、およびインフラストラクチャコードと対話できます。

タマネギの建築は好きではありません。

于 2013-03-20T19:16:55.497 に答える
0

あなたの主な関心事は、データ モデルから取得されるデータの量とビュー モデルで必要なデータの量であるという事実を考慮すると、データベースとそれぞれのデータ モデルでビューを構築することが正しいアプローチであると言えます。 .

これにより、1 回の旅行でデータベースから活用されるデータの量を削減できます。

データ モデルはビュー モデルをほぼ模倣しますが、それは問題ではなく、2 つの異なる目的を果たします。ビュー モデルは、ビューがバインドされるためのものです。データ モデルは、データを取得および保存する方法を認識しています。これらのビューを構築することで、最適な方法でデータを取得できます。さらに、同じモデルにカスタム保存ロジックを格納して、必要に応じて書き込み可能にすることができます。したがって、ある層から次の層にデータを移動することを超えたデータ モデルの必要性が生じます。

于 2013-03-20T18:52:18.470 に答える