3

私はDIと単体テストを始めたばかりで、経験豊富な開発者にとっては簡単なことだと確信している障害にぶつかりました:

データを受信して​​データベースに保存する MessageManager というクラスがあります。同じアセンブリ (Visual Studio のプロジェクト) 内で、データベースへのアクセスに必要なすべてのメソッドを備えたリポジトリ インターフェイスを作成しました。このインターフェイスの具体的な実装は、DataAccess という別のアセンブリにあります。

そのため、DataAccess は、リポジトリ インターフェイスについて知るために MessageManager へのプロジェクト参照を必要とします。また、MessageManager のクライアントがリポジトリ インターフェイスの具体的な実装を挿入できるように、MessageManager には DataAccess へのプロジェクト参照が必要です。これはもちろん許可されていません

インターフェイスをデータ アクセス アセンブリに移動することもできますが、リポジトリ インターフェイスは、それを使用するクライアントと同じアセンブリに存在することを意図していると思います

それで、私は何を間違ったのですか?

4

7 に答える 7

3

どちらのアセンブリからもインターフェイスを分離する必要があります。インターフェイスを消費者または実装者と一緒に配置すると、インターフェイスを持つ目的が無効になります。

インターフェイスの目的は、DataAccess オブジェクトが属するアセンブリと同じかどうかに関係なく、そのインターフェイスを実装する任意のオブジェクトを挿入できるようにすることです。一方、具体的な実装を消費する必要なく、MessageManager がそのインターフェイスを消費できるようにする必要があります。

インターフェイスを別のプロジェクトに配置すると、問題は解決します。

于 2008-09-18T04:21:06.867 に答える
2

インターフェイスを保持するアセンブリを追加するか、インターフェイスを DataAccess アセンブリに移動するかの 2 つの選択肢しかありません。DataAccess クラスがいつの日かリポジトリ インターフェイスの別の実装者 (別のアセンブリであっても) に置き換えられる可能性があるアーキテクチャを開発している場合でも、それを DataAccess アセンブリから除外する理由はありません。

于 2008-09-18T04:20:18.617 に答える
1

制御の反転を使用していますか?もしそうなら、答えは簡単です。

アセンブリAには次のものが含まれます。

  • MessageManager
  • IRepository
  • ContainerA(MessageManagerを追加)

アセンブリBには次のものが含まれます(およびrefのAssemblyA):

  • リポジトリはIRepositoryを実装します
  • ContainerBはContainerAを拡張します(リポジトリを追加します)

アセンブリC(またはB)は、アプリを起動し、MessageManagerIRepositoryを解決する方法を知っているMessageManagerのコンテナーを要求します。

于 2008-09-18T05:32:53.013 に答える
1

リポジトリ インターフェイスを DataAccess アセンブリに移動する必要があると思います。その後、DataAccess は MessageManager を参照する必要がなくなりました。

ただし、私はあなたのアーキテクチャについてほとんど何も知らないので、言うのは難しいままです...

于 2008-09-18T04:18:50.617 に答える
1

多くの場合、コンストラクター注入の代わりにセッター注入を使用して、循環参照の問題を解決できます。

擬似コード:

Foo f = new Foo();
Bar b = new Bar();
f.setBar(b);
b.setFoo(f);
于 2008-09-18T04:22:06.443 に答える
0

依存性逆転の原則が機能しています:

高レベルのモジュールは、低レベルのモジュールに依存するべきではありません。どちらも抽象化に依存する必要があります。抽象化は詳細に依存するべきではありません。詳細は抽象化に依存する必要があります。

DatAccessアセンブリのクラスが依存する抽象化は、DataAccessクラスおよびその抽象化の具体的な実装(MessageManager)とは別のアセンブリにある必要があります。

はい、それはより多くのアセンブリです。個人的にはそれは私にとって大したことではありません。余分なアセンブリに大きなマイナス面は見られません。

于 2008-09-18T20:32:52.100 に答える
-1

構造を現在の状態のままにして(問題の原因となるMessageManagerからDataAccessへの依存関係なしで) 、クラスMessageManagerを使用して実行時に必要な具体的な実装を動的にロードすることができます。System.Reflection.Assembly

于 2008-09-18T04:34:46.723 に答える