web-dev-qa-db-ja.com

DDDインフラストラクチャレイヤー:サービス+永続性または永続性のみを実装する

簡単な紹介:.NET、Entity Framework(EF)をORMとして使用し、永続化のためにSQL Serverを使用して、アプリケーションを構築します。 SQL Serverに関する私の知識は単純な要求をはるかに超えており、私はそれを使用してDB操作を大幅に削減します。それでも、可能な場合は直接SQLを書くのをやめるためにEFを使用することを好みます。

アプリケーションサービスがあります。コアに実装したいIDogsService。実装にはEFコンテキスト(リポジトリ)が挿入され、挿入されたコンテキストを永続化に使用する必要があります。 DDDによると、これは私のアーキテクチャがそうあるべきだと私は信じています。

しかし、私はすべてを別様に行います。 IDogsServiceインターフェイスはコアにありますが、実装は別のプロジェクトにあります。また、その実装にはリポジトリが注入されていません。同じプロジェクトで定義された内部dbコンテキストを使用するだけです。そのような決定の理由は単純です。コアはリポジトリについて何も知らない一方で、IDogServiceの実装は、永続化に関しては、望んだとおりに動作する可能性があるためです。そして、コアはリポジトリをまったく気にするべきではないと思います。

そのようなアプローチの長所:私のdbコンテキストはSQL Serverのすべての利点を使用できるため、パフォーマンスが向上します。短所:サービスのビジネスロジックがコアの外に移動します(コアにとどまる必要があると思います)。

私はこれらすべてが間違っていると強く感じており、少し異なる設計にする必要があります。しかし、方法がわかりません。他のRDBMSに有利なSQL Serverの利点がなくなるため、私は本当にリポジトリパターンに目を向けたくありません。

共有する経験はありますか?

3
Dima

依存関係の逆転の原則 のように自己がねじれているかのように聞こえます。

グレッグ・ヤングの 2009年の一般リポジトリに関するエッセイ を長く読むことをお勧めします。 TL; DRは、一般的なケースでは、明確な定義のある契約を好むということです。

数年前に書いたUdi Dahan 同様のアイデアがあった

しかし、基本的なプロットは、ドメインコードがコントラクトインターフェイスを介してできる限り明確にそのデータニーズを記述するということです。永続化コンポーネントは、これらのコントラクトに可能な限り効率的に対応する実装を提供し、 composition roots はすべてを相互に結び付けます。

短所:サービスのビジネスロジックがコアの外に移動される

私はそれが否定的であることに同意しますが、ビジネスモジュールで永続化ソリューションの実装を指定しようとしない限り、それは起こらないはずです。

もちろん、DBにとらわれないリポジトリパターンに戻すこともできますが、パフォーマンスが低下します。

ダメダメダメ; DBにとらわれないことは問題ありません-実装に十分な情報を提供できないのは(おそらく)あいまいな契約であるため、問題が発生します。

懸念事項は別にしてください。ただし、ユースケースが一部の機能に完全に適合していることを認識する実装が利用できるように、コントラクトを明確にしてください。

多くの場合、このパターンは、コアドメインに必要なものを説明するインターフェイス、適切に機能できる最適化された実装、2つの間のネゴシエーション方法を理解する中央のシンアダプターのように見えます。

Mark Seemannのブログには 依存関係の概要 も含まれています。

3
VoiceOfUnreason

あなたはデータアクセスレイヤーを備えたビジネスレイヤーだと思います。 IDogServiceがビジネスロジックを実行し、コンテキストを使用してdb呼び出しを書き込むことは、SRPの違反です。データアクセス層をドメイン層から分離することが実際に必要なようですが、それらを抽象化せずに実際にそれを行うことはできません...リポジトリパターンを使用してください。

IDogService実装(DogService)がビジネスロジックのみを実行し、IDogRepositoryに依存するようにします。別のプロジェクトでDogRepositoryを使用しながら、これらの3つのクラスをコアに保持します。 2つの問題を解決します。1つのSRP違反です。DogServiceの場合も、オープン/クローズの原則に違反する必要がないため、Posgressに簡単に切り替えることができます。