私はリポジトリの実装についてたくさん読んでいます。数年でMS SQL ServerからNoSQLにdbが移行したため、プロジェクトにどのように実装するかについて混乱しています。
見た目がすっきりしているので、インプ#1に傾いています。しかし、私が読んだ専門家のいくつかの説明はimp#2を使用しています。状況に応じて使い分けるべき理由は明確だと思います。理想的には、別のデータベースへの切り替えをできるだけ簡単にしたいです。
BLLにリポジトリのインターフェイスを配置する主な理由は、個別のDALへのハード参照を回避するためですが、代わりに、変更するDALが安定したBLLを参照するようにします。
安定したBLLを変更せずに実装を交換できるようにするため
インターネットでは、これが一般的な主な理由ではないかもしれませんが、これは私があなたの状況でオプション2を選ぶことを強いる理由です。
DI(依存性注入)コンテナーを使用していると仮定します。たとえば、構成ファイルを使用してこれを構成する場合、BLLのリポジトリインターフェースの実装はDAL.Sqlプロジェクトにあることをコンテナに伝えます。 NoSQLソリューションに切り替えたら、DAL.NoSQLプロジェクトを作成してデプロイし、DIコンテナー構成を変更して、新しいプロジェクトからリポジトリーの実装を解決します。新しいDALは、変更する必要のない安定したBLLに依存しています。
ただし、オプション1を使用する場合、DALプロジェクトをホットスワップできない可能性があります。たとえば.NETを使用している場合、BLLプロジェクトが特定のバージョンのDAL dllに依存している問題に遭遇する可能性があり、BLLを変更しないとDALをスワップアウトできません。
リポジトリインターフェイスはBLLの一部であるため
リポジトリは、アプリケーションがデータを取得する方法を定義する単なるゲートウェイです。その意味では、ドメインオブジェクトと同じくらいビジネスロジックの一部です。具体的な実装は変更される可能性がありますが、インターフェース自体はビジネスロジックの一部です。
BLLを分離するため
DALにインターフェイスと実装があることは、すべてのDALをBLLに取り込むことを意味します。開発者がDALプロジェクトのオブジェクトを使用すべきでない方法で使用するのを妨げるものは何もありません。 DALがBLLに依存しているということは、BLLには必要なインターフェイスのみを含めることができることを意味します。
ドメインオブジェクトを持つ別のプロジェクトを回避するため
DALとBLLはどちらもドメインオブジェクトに依存しています。 BLLにリポジトリとドメインオブジェクトを使用するクラスがある場合、循環参照を作成するため、DALにリポジトリインターフェイスを配置することはできません(BLLにはDALのリポジトリのインターフェイスが必要、DALにはBLLのドメインオブジェクトが必要です)。したがって、BLLがドメインを参照し、DALがドメインを参照できるように、BLLとドメインオブジェクトを2つのプロジェクトに分割する必要があります。
オプション1を使用すると、1つのデータベースから別のデータベースに切り替えるときに最小限の変更を行うことができます。したがって、データベースに関連するファイルのみを変更する必要があるため、変更によるアプリケーションへの影響は最小限になります。
ビジネス層およびデータベースを処理しないその他の層は、気にする必要も、実装の詳細を知る必要もありません。したがって、...と言及すると、BLLはこのレイヤーに依存します一連のインターフェイスがあると想定していますが、 IUserRepository
など、またはGetUserByName(string name)
などのメソッドを定義するようなもの.
リポジトリの上のレイヤーはこれらのインターフェイスを使用してデータのニーズに合わせます。これにより、ビジネスレイヤーはリポジトリレイヤーが提供するものを知ることができますが、実装の詳細は含まれません。したがって、ビジネスレイヤーに関する限り、変更を行っても何も変更されません(リポジトリレイヤーによって提供される機能に変更を加えないと想定)。
@JDTの答えは正しいです。 Imp#2がより良いオプションです。 Robert C. Martinによって記述された依存関係逆転原理(DIP)は、2つのモジュールA
とB
、およびIB
によって実装され、B
に注入されたインターフェイスA
がある場合、IB
の定義はA
のコンテキスト内にある必要があることを暗黙的に要求します。
実際、これを要求するのはDIPの2番目の句です。
抽象化は詳細に依存すべきではありません。詳細は抽象化に依存する必要があります。
BLLおよびDALの場合、BLLは高レベルモジュールであり、DALは低レベルモジュールです。抽象化(リポジトリのインターフェイスなど)がDAL内で定義される場合、抽象化(インターフェイス)は詳細(実装)に依存します。詳細が変更された場合(NoSQL DB実装に切り替えた場合など)、抽象化/インターフェースも変更され、高レベルモジュール(BLL)も変更する必要があります。そして、これは望ましくありません。したがって、あなたの質問に対する答えは明らかにオプション#2です。
これをバックアップするためのいくつかのソースを簡単に探して、これを Wikipedia on the DIP で見つけました:
高レベルコンポーネントが必要とする動作/サービスを定義するインターフェースは、高レベルコンポーネントのライブラリによって所有され、その中に存在します。低レベルコンポーネントによる高レベルコンポーネントのインターフェースの実装では、低レベルコンポーネントパッケージがコンパイルのために高レベルコンポーネントに依存する必要があるため、従来の依存関係が逆になります。