2017-10-25 15 views
0

私が正しく理解していれば、CQRSは書き込みと読み取りの責任分担についてです。だから私は書き込みモデルでリポジトリを使うことができます。たとえば、var user = repository.GetUserById(); - これはidでユーザーを取得し、repository.UpdateUser(user);は変更されたプロパティでユーザーを更新します。読み取りモデルでは、より複雑なDTOのを構築することができます。リポジトリでCQRSを使用する

public class UsersReadModel 
    { 
     private IMyContext context; 
     public UsersReadModel(IMyContext context) 
     { 
      this.context = context; 
     } 

     public ComplexUserDTO GetComplexUser(ISelectQuery query) 
     { 
      ComplexUserDTO user = new ComplexUserDTO(); 

      // get all user properties, GetUser by id 
      user.UserDTO = context.Users.Where(d => d.UserId == query.UserId).ProjectTo<UserDTO>().FirstOrDefault(); 

      //here I don't need everything from PoliciesTable, I just need two columns, so I use anonymous object 
      var policieObject = context.Policies.Where(f => f.BasePolicyId == query.PolicyId).Select(s => new { s.PoliciesNames, s.Clients.Select(d => d.ClientNames).ToList() }).FirstOrDefault(); 

      user.PoliciesNames = policieObject.PoliciesNames; 
      user.ClientsNames = policieObject.ClientsNames; 
      return user; 
     } 

    } 

私はDTOにマッピングする必要がある、と私の読み取りモデルではありませんので、だから私の書き込みモデルでは、私は、私のリポジトリからIDでユーザーを取得します私はIDでGetUserを使用しますが、私はそれを必要とするので、DTOにマップします。このコードを繰り返すのではないですか?(私はIDでユーザーを取得したい場合、両方の場所で変更する必要があります)私の読み込みモデルでリポジトリを使用することはできますか?この場合、私はUsersReadModelのリポジトリとコンテキストの両方を使用しなければなりません(匿名オブジェクトとテーブル列の一部を選択する)。

答えて

2

ドメインが非常にシンプルな場合、書き込みと読み取りは非常によく似ていて、大量の重複が発生します。実際、これは逆も同様です.WriteモデルがReadモデルと非常によく似ている場合は、CRUDとして実装することができ、は必ずにCQRSが必要です。

読み取りモデルでリポジトリを使用できますか?

何かあなたは読み取り側にしたいと思います。両側は多くの視点から分離されている。

CQRSでは、コードの重複が発生するケースが多くあります。それを恐れないでください。共有クラスでそれを抽出することができます。

P.S. すべての書き込みモデルではなく、すべてのユースケースに対して読み取りモデルを用意する必要があります。 Write to Readの1対1の対応がある場合、となります。これは、CRUDを使用してこれを実装する必要があることを意味します。

P.S.私は非常に最適化されたReadモデル(異なる永続性タイプ、JOINS、カスタムデータシャーディングなど)を持っているので、ドメインがシンプルであってもCQRSを使いたいです。

2

ここではいくつか注意する点があります。あなたの説明から、読んだモデルと書いているモデルの間には隔たりがあるようには聞こえません。彼らは非常に異なる目的を持っていることを忘れないでください

CQRSは、ドメイン主導型の設計原則に大きく依存しています。主な原則は、ドメインオブジェクトのカプセル化です。

その結果、ドメインオブジェクトに「プロパティ」(特にセッターではない)があるとは思われません。それは例えばIDがあるかもしれませんが、それほど多くはありません。これは、それ自身の中の不変量を保護する役割を果たすからです。あなたがセッターを持っていれば、簡単にできることではありません。

また、私は、ドメインオブジェクトが本当にid以外のゲッターを持つべきではないと主張します。良い読み込みモデルがあれば、それらの必要性はほとんどなく、オブジェクトの誤った使用を促すかもしれません。このアイデアが少し緩和できる時があります。今は私は考えることはできませんが。

その結果、ドメインオブジェクトのリポジトリは非常に簡単になります。 GetByIdとSave(イベントソーシングを使用していない限り、これは別のトピックです)。

読むモデルは、他の一方で、UIを提供するように形成されなければなりません。各モデルには、さまざまなソースからのデータが混在している可能性があります。たとえば、ユーザーの詳細をコンテキスト、アクティビティ、オーダー、または会社に評価したり、アプリケーションの目的が何であっても見たい場合があります。

CQRSアプリケーションの典型的な構造のこの説明は役に立つかもしれ:CQRS + Event Sourcing - A Step by Step Overview

そして、これはドメインオブジェクトを作成するにあなたにいくつかの洞察力を与えることがあります。このことができますAggregate Root - How to Build One for CQRS and Event Sourcing

希望を。

1

私が正しく理解していればCQRSは、書き込みを割ると責任を読みについてです。

これは、サポートしているユースケース用に設計されたデータモデルを持っていることに近いということです。

私たちは真実を持っている、そしてその真実は、複数の表現を持っています。私たちは今を「ブックレコードの」表現を更新することができ、我々は最終的にクエリをサポートするために使う表現 -

トリックは表現が時間内に結合する必要がないことです。

読み取りモデルでリポジトリを使用できますか?

絶対に。魔法はありません。

のUdi漢はおそらく、あなたは何をしているかに応じて、読み取りモデルの異なる明示的表現を提供する、あなたのリポジトリにおよそdifferent repositories、または多分より正確な方法を考えていることを示唆しています。各メソッドは、その特定のユースケースに必要な表現をロードします。

関連する問題