ドメインエンティティには永続性に関連するコードを含めるべきではないため、永続性を無視する PIである必要があります
ドメインモデル DMが関心を持っているデータは、ドメインエンティティのナビゲーションプロパティを介して、または上位層(つまり、UI層またはサービス層)によってDMに配信できます。
ただし、特定のドメインエンティティが必要なデータを動的に決定する必要があるシナリオでは、そのエンティティがリポジトリなどのコンポーネントを介してそのデータを要求することは完全に許容できると思いました。
このリポジトリが永続層から完全に分離されている場合、エンティティはPIに違反していません。これは、データを取得する方法がまだわからないため、リポジトリからデータを要求することによってのみデータを取得することを認識しているためです。
class Customer
{
public string InterestedWhatOtherCustomerOrdered( ... )
{
...
var orders = repository.Find...;
...
}
...
}
そのため、ドメインコードが、上位層またはナビゲーションプロパティからデータを受信するだけでなく、リポジトリから必要なデータを要求できるようにすることは、なぜ悪い習慣と見なされるのでしょうか。
つまり、Fowler(データマッパーに関するPEAAの章)によると、ドメインコードに必要なメソッドをデータマッパーからインターフェイスクラスに抽出して、ドメインコードで使用できるようにすることは問題ありません。
セバスチャングッドへの返信:
1)
アイデアは、ドメインモデルがそのデータがどこから来たのかについての詳細に関係するべきではないということです。
ただし、ドメインエンティティがPIルールに準拠している場合、データが実際にどこから来たのかについての詳細を知らないと主張することができます。
2)それでもそのデータをロードする方法を決定する必要がありますが、「アプリケーションサービス」に(通常は)それについて心配させます。
a)実世界のエンティティが特定のデータを検索する機能を持っていると仮定すると、データを要求するドメインエンティティに問題があると見なしますか(申し訳ありませんが、そのような一般的な質問に答えるのは難しいことを認識しています)?
b)最も重要なことは、アプリケーションサービスレイヤーが、ドメインエンティティが処理に必要とする可能性のあるさまざまな種類のデータすべてをどのように予測できるかを理解するのに苦労しています。
つまり、アプリケーション層サービスがデータの読み込みを単独で担当しないということは、ドメインエンティティの内部ロジックを変更するたびに(このエンティティ が異なるタイプのデータを必要とするように)、アプリケーションサービスも変更する必要があることを意味しますしたがって、古いデータではなく新しいタイプのデータをエンティティに提供するようになりますか?!
Eulerfxへの返信:
1)
a)The application service can provide not only data, but a mechanism for retrieving data as well, in cases where it is better to place logic for determining the exact instance of data needed in the domain
したがって、ドメインで必要なデータの正確なインスタンスを決定するためのロジックを配置する方がよい場合は、サービスS内のリポジトリへのアクセスをカプセル化してから、ドメインエンティティのメソッドへの引数としてSを渡す必要がありますか?したがって、この例では、内部サービスへのアクセスをカプセル化してから、引数として:に渡す必要があります。 OrderRepository
ordersSelectorService
ordersSelectorService
Customer.InterestedWhatOtherCustomerOrdered
class Customer
{
public string InterestedWhatOtherCustomerOrdered(OrdersSelectorService ordersSelectorService)
{
...
var orders = ordersSelectorService.Select...;
...
}
...
}
class CustomerService
{
OrdersSelectorService ordersSelectorService;
CustomerRepository customerRepository;
public void ()
{
var customer = this.customerRepository.Get...;
...
customer.InterestedWhatOtherCustomerOrdered(ordersSelectorService);
...
}
}
OrderRepository
b)それが実際にあなたが提案していることである場合、単に引数として渡すことよりも他の利点がありますか(すでに述べたもの以外に)Customer.InterestedWhatOtherCustomerOrdered
:
class Customer
{
public string InterestedWhatOtherCustomerOrdered(CustomerRepository orderRepository)
{
...
var orders = orderRepository.Select...;
...
}
...
}
2)次の質問は、あなたの投稿全体を正しく理解したことを確認するためのものです。
So if a specific behavior requires access to some service, have the application service provide an abstraction of that service as an argument to the corresponding behavior method. This way, the dependency upon the service is explicitly stated in the method signature.
a)「特定の動作」とは、ドメインエンティティ(つまりCustomer
)を指しているのですか?!
b)「引数としてそのサービスの抽象化を提供するアプリサービス」が何を意味するのか正確にはわかりません。おそらく、サービス S自体(ie OrderRepository
)をメソッド(ie Customer.InterestedWhatOtherCustomerOrdered
)の引数として提供する代わりに、クラス C(ie )でSOrdersSelectorService
をカプセル化してから、 Cをメソッドの引数として渡す必要がありますか?
c)C ( Sをカプセル化するクラス< -b)の質問を参照))は常にアプリケーションサービスであり、Sは常にCによってカプセル化される必要があると仮定します( Sがすでにアプリケーションサービスである場合を除く)?はいの場合、なぜですか?
d)
このように、サービスへの依存関係はメソッドシグネチャに明示的に示されます。
メソッドシグネチャに明示的に記述されているサービスに依存することで、どのようなメリットが得られますか?メソッドのコードを検査しなくても、メソッドが何をしているのかをすぐに知ることができるということだけですか?
3)少し外れたトピックですが、メソッドM( )の引数として動作BをクラスCに注入すると、依存性注入とは呼ばれませんが、代わりにコンストラクターまたはセッターを介してBがCに注入された場合に表示されます( )、それからそれを依存性注入と呼びます。何故ですか?C.M(B b);
B b=new B();C c=new C(b);
Eulerfxへの2回目の返信:
1)
1ab)...別のオプションは、OrdersSelectorServiceの代わりにラムダを使用することです。
に渡す代わりに、Customer.InterestedWhatOtherCustomerOrdered内でLinq-to-Entities(ラムダに大きく依存している)OrdersSelectorService
を使用する必要Customer.InterestedWhatOtherCustomerOrdered
があることを意味していると思います。しかし、私が知る限り、これは永続性無視ルールに違反します(私の前のスレッドを参照してください)
2)
2c)いいえ、Cは必要なメソッドを含むインターフェースである必要があります。サービスSは、そのインターフェイスを実装することも、その場で実装を提供することもできます。
ああ、 Cはアプリケーションサービスであるべきだとあなたが提案していると誤解しました。とにかく、Cはどこに住むべきですか?アプリケーションサービスアセンブリ内またはドメインモデルアセンブリ内にパックする必要がありますか?
3)
2d)...クラス自体のコンストラクターとは対照的に、メソッドシグネチャで依存関係を宣言する利点は...もう1つの利点は、ドメインクラスがIoCコンテナーからの依存関係グラフの一部である必要がないことです-make物事はもっと簡単です。
IoCについてはまだよくわからないので、ドメインクラスがIoCの依存関係グラフの一部になるのはどの程度正確かを尋ねる必要があります。つまり、このドメインクラスはIoCの構成レイヤー内で指定する必要があります(このレイヤーは、依存関係のインターフェイスと実際の依存関係の実装との間のマッピングを指定するためにのみ使用されると思いました。したがって、依存クラスは均等ではないと想定しました。このレイヤー内で言及)または...?
4)トラブルを引き起こしたり、あなたの一人が間違っていることを暗示したりするつもりはありません(あなたの両方があなたのデザインを好む理由をすでに推論しています)が、私はあなたの投稿を完全に理解したことを確認したいと思います。実際、 nwang0が提案しているのとは正反対のことを推奨しています(つまり、両方が同じことを推奨している場合、私の理解力には修復が必要です:o)?!
ありがとうございました