3

これはほとんどの人にとって明白に思えるかもしれませんが、依存性注入 (DI) がインターフェイスの使用に依存していることを確認しようとしているだけです。

より具体的には、特定のインターフェイスをコンストラクターのパラメーターとして持つクラス、またはプロパティとして定義された特定のインターフェイス (別名セッター) を持つクラスの場合、DI フレームワークは、ニーズを満たすために具体的なクラスのインスタンスを渡すことができます。そのクラスのそのインターフェイスの。(この説明が明確でない場合は申し訳ありません。用語/概念がまだ私にとって少し新しいため、これを適切に説明するのに苦労しています。)

私が尋ねる理由は、現在、ある種の依存関係を持つクラスを持っているからです。オブジェクトの依存関係ではなく、URL です。クラスは次のようになります [C#]:

using System.Web.Services.Protocols;
public partial class SomeLibraryService : SoapHttpClientProtocol 
{
        public SomeLibraryService() 
        {
            this.Url = "http://MyDomainName.com:8080/library-service/jse";
        }
}

SoapHttpClientProtocol クラスには、Public プロパティUrl(これは単純な古い「文字列」) があり、ここのコンストラクターはそれをハードコードされた値に初期化します。

DIフレームワークを使用して、構築時に別の値を注入することはできますか? 私はそうでthis.Urlはないと思っていInterfaceます。それはStringです。

[ちなみに、私が作業しているコードのコメントによると、上記のコードは「wsdl によって自動生成された」ものでした。したがって、このコードを特に変更したくはありませんが、自分で再生成することもありません。したがって、このコードを変更しても問題ないかもしれません。]

文字列をパラメーターとして取り、そのように初期化する代替コンストラクターを作成しているのを見ることができましたが、this.Url疎結合の懸念の分離を維持することに関して、それが正しいアプローチであるかどうかはわかりません。(SoC)

この状況に対するアドバイスはありますか?

4

4 に答える 4

8

DI は、クラスが外部依存関係を構築せず、それらの依存関係の有効期間を管理しないことを意味します。依存関係は、コンストラクターまたはメソッド パラメーターを介して注入できます。インターフェイスまたは抽象型は、消費者がその依存関係から期待するコントラクトを明確にするために一般的ですが、場合によっては単純型も注入できます。

たとえば、ライブラリ内のクラスは HttpContext.Current を内部的に呼び出す可能性があり、これにより、コードがホストされるアプリケーションについて任意の仮定が行われます。ライブラリ メソッドの DI バージョンは、HttpContext インスタンスがパラメーターなどを介して注入されることを期待します。

于 2010-07-15T15:24:53.077 に答える
5

インターフェイスを使用する必要はありません。具象型または抽象基本クラスを使用できます。しかし、DI の利点の多く (依存関係の実装を変更できるなど) は、インターフェイスを使用するときに得られます。

Castle Windsor (私が最もよく知っている DI フレームワーク) を使用すると、IoC コンテナー内のオブジェクトをインターフェイスまたは単に名前にマップすることができます。

于 2010-07-15T15:25:39.380 に答える
3

依存性注入は、コードを整理する方法です。おそらく、あなたの混乱の一部は、それを行うための公式の方法が1つもないという事実から来ています. これは、「通常の」c# コードを使用するか、Castle Windsor のようなフレームワークを使用して実現できます。ときどき (頻繁に?) これにはインターフェースの使用が含まれます。どのように達成されたとしても、DI の全体的な目標は通常、コードをテストしやすくし、後で変更しやすくすることです。

コンストラクターを介して例に URL を挿入する場合、それは「手動」DI と見なすことができます。DI に関するウィキペディアの記事には、手動 DI とフレームワーク DI の例が他にもあります。

于 2010-07-15T16:54:58.373 に答える
0

.NET アプリケーションでのインターフェイスの使用に焦点を当ててお答えしたいと思います。.NET のポリモーフィズムは、仮想メソッドまたは抽象メソッド、またはインターフェイスを通じて実現できます。

いずれの場合も、実装がまったくないメソッド シグネチャ、またはオーバーライド可能な実装があります。

関数 (またはプロパティ) の「コントラクト」は定義されていますが、メソッドの実装方法、メソッドの論理的な根幹は実行時に異なる可能性があり、どのサブクラスがインスタンス化され、メソッドまたはコンストラクターに渡されるかによって決定されます。またはプロパティに設定します(「注入」の行為)。

公式の .NET 型の設計ガイドラインでは、インターフェイスよりも抽象基底クラスを使用することを推奨しています。これは、出荷後に抽象基底クラスを展開するためのより優れたオプションがあり、便利なオーバーロードを含めることができ、正しい使用法を自己文書化して実装者に伝えることができるためです。

ただし、ロジックを追加しないように注意する必要があります。そうする誘惑は過去に人々を悩ませてきたので、多くの人がインターフェイスを使用しています - 他の多くの人々は単に周りに座っているプログラマーがそうしているのでインターフェイスを使用しています。

DI 自体が過度に使用されることはめったにありませんが、インジェクションを実行するためにフレームワークを使用することは、複雑さの増加を損なうために過度に使用されることが非常に多いことを指摘することも興味深いです。それらは決して「切り替え」られていませんが、コンテナ内にあります。

IoC フレームワークは控えめに使用する必要があります。通常は、環境または構成に従って、実行時にオブジェクトを交換する必要がある場合にのみ使用してください。これは通常、データ層を抽象化するために使用されるリポジトリ オブジェクトなど、アプリケーション内の主要コンポーネントの「継ぎ目」を切り替えることを意味します。

私にとって、IoC フレームワークの本当の力は、作成を制御できない場所で実装を切り替えることです。たとえば、ASP.NET MVC では、コントローラー クラスの作成は ASP.NET フレームワークによって実行されるため、何も注入することはできません。ASP.NET フレームワークには、IoC フレームワークが作成プロセスの「間に入り」、その魔法を実行するために使用できるいくつかのフックがあります。

ルーク

于 2013-11-15T15:11:24.597 に答える