0

Entity Framework を使用して WinForms アプリケーションで N 層設計を開発しようとしています。

次のサンプル フローは、Entity Framework を使用して n 層設計で新しいレコードを保存する場合に正しいですか?

  1. プレゼンテーション層

    A) UI は、ライト スクリーン入力データの検証を実行します。次に、UI はビュー モデルを DTO に変換し、それをアプリケーション層に渡します。

  2. アプリケーション層

    A)アプリケーション層はDTOをドメイン層のドメインモデルに送信します

  3. ドメイン層

    A) ドメイン モデル SoftwareRequest エンティティの新しいインスタンスを作成する前に、ビジネス ルールに準拠するために着信 DTO 値を検証します。

    B) すべての値が検証されたら、ドメイン モデル SoftwareRequest エンティティの新しいインスタンスを作成します。

    C) 終了してアプリケーション層に制御を戻す

  4. アプリケーション層

    A) Infrastructure Layer SoftwareRequest リポジトリを呼び出し、ドメイン モデルによって提供された新しいドメイン モデル SoftwareRequest エンティティを渡します。

  5. インフラストラクチャ層のデータ アクセス

    A) SoftwareRequest リポジトリは、アプリケーション層から新しいドメイン モデル SoftwareRequest エンティティを受け取ります。

    B) 新しいドメイン モデル SoftwareRequest エンティティをエンティティ フレームワーク DBContext に追加する - context.SoftwareRequests.Add(NewDomainModelEntity)

    C) 新しいエンティティを保存する - context.SaveChanges()

    D) 終了して制御をアプリケーション層に戻す

  6. アプリケーション層

    A) 保存操作の結果を DTO に変換する

    B) 終了して、新しい SoftwareRequest を追加した結果を含む DTO を使用して制御を UI に戻します。

  7. UI

    A) 受信した DTO を View Model に変換する

    B) View Model データを画面に表示し、新しいソフトウェア要求を追加した結果を示します。

--------- 2016 年 2 月 22 日午前 6 時 49 分 (PST) に追加された以下の情報 ---------

依存関係の概要:

プレゼンテーション層 - アプリケーション層を参照してリクエストを行います - UI から送信されるかアプリケーション層から受信される DTO を記述するインターフェイスを操作する目的でのみドメイン層を参照します

アプリケーション層 - DTO を記述するドメイン層インターフェースを参照します。また、ドメイン モデル エンティティのインターフェイス定義を使用して、インフラストラクチャ レイヤーからのエンティティ応答を UI に返される DTO に変換できるようにします。インフラストラクチャ レイヤー データ アクセスへの参照もここにあるため、関連するドメイン モデル エンティティがドメイン レイヤーによってルールと値について検証された後、CRUD 操作を実行するためにリポジトリにアクセスできます。

ドメイン レイヤー - 上下のレイヤーへの参照はありません。どのレイヤーからも依存関係が注入されたサービスはありません。これには、インフラストラクチャ リポジトリでの CRUD を含むタスクは含まれません。ルールの検証などのすべての要求は、要求されたドメイン タスクを実行するために必要なすべての情報を含む DTO を受け取ります。

インフラストラクチャ レイヤー データ アクセス - リポジトリでエンティティ フレームワーク操作 (つまり、CRUD 操作) を実行するために使用されるドメイン モデル エンティティを記述するドメイン レイヤー インターフェイスを参照します。ここでインフラストラクチャ層のデータ アクセスに実装されているリポジトリのインターフェイスの定義については、ドメイン層も参照します。この層では DTO は使用されません。この層は通常、ドメイン モデル エンティティでアプリケーション層に応答します。アプリケーション層は、すべてのドメイン モデル エンティティの応答 (IEnumerable など) を DTO に変換し、UI に送り返します。

4

1 に答える 1

1

あなたの説明に基づいて、DTO タイプはドメイン層で宣言されていると思われます。クライアントが変更されると DTO が変更される可能性があり、クライアントが進化するたびにドメインを変更したくないため、実際にはそれらが属する場所ではありません。confirmPasswordまた、DTOには、ドメインに関係のないユース ケース レベルのフィールドを含めることができます。

もう 1 つのことは、アプリケーション層はビジネス トランザクションを制御することであり、ドメインの単なるファサードではないということです。

調整方法は次のとおりです。

  1. アプリケーション層

    A)アプリケーション層は、コンストラクターまたは構築が複雑な場合はファクトリーを呼び出すことにより、DTOを新しいエンティティにマップします

  2. ドメイン層

    A)エンティティ コンストラクタまたはファクトリで、エンティティが初期化される値を検証します (非 null 可能性、値の範囲、依存引数など)。

    B) 終了して制御をアプリケーション層に戻す

...

  1. インフラストラクチャ層のデータ アクセス

    A) SoftwareRequest リポジトリは、アプリケーション層から新しいドメイン モデル SoftwareRequest エンティティを受け取ります。

    B) 新しいドメイン モデル SoftwareRequest エンティティをエンティティ フレームワーク DBContext に追加する - context.SoftwareRequests.Add(NewDomainModelEntity)

    C)終了して制御をアプリケーション層に戻す

  2. アプリケーション層

    A)新しいエンティティを保存する - context.SaveChanges()

    B) 保存操作の結果を DTO に変換する

ビジネス トランザクション制御をインフラストラクチャ レイヤーからアプリケーション レイヤーに移動する際、新しい抽象化 (通常は Unit of Work) を導入して、Entity Framework のDbContext.

編集:これを説明するサンプル

/* Application layer */

public class SoftwareRequestDTO
{
    public string Name { get; set; }
    // your other SoftwareRequest data here
}

public class SoftwareRequestApplicationService
{
    // constructor etc...

    public void CreateSoftwareRequest(SoftwareRequestDTO dto)
    {
        using (var transaction = new BusinessTransaction()) // UoW or whatever - can also be constructor injected into the service
        {
            var softwareRequest = new SoftwareRequest(dto.Name);
            _softwareRequestRepository.Add(softwareRequest);
            transaction.Complete();
        }
    }
}

/* Domain layer */

public class SoftwareRequest
{
    public SoftwareRequest(string name)
    {
        // validation/guard clause
        if (name == null)
        {
            throw new DomainException("SoftwareRequest name cannot be null");
        }
        // your assignments here
    }
}
于 2016-02-23T12:34:22.970 に答える