3

私は数日間、依存性注入/制御の反転について読んでいて、概念を理解するのに苦労しています。

私が次の些細なシナリオを持っていると仮定しましょう:

public interface ILocation
{
    string LocationName { get; set; }
}

// The implementation / concrete class for ILocation
public class Location : ILocation
{
    public string LocationName {
        get { /* logic */ }
        set { /* logic */ }
    }
}


// My class that depends on ILocation as a dependency
public class SomeClass{
    public SomeClass(ILocation location)
    {
        this.theLocation = location;
    }

    // 
    // more code...
    // 
}

すばらしいので、ILocation注入されましたSomeClass...しかし、依存性注入フレームワークIN CODE内ILocationで処理されるように接続しLocation、コンパイルする必要がありました。(余談ですが、ファイルでこの構成を行うフレームワーク、つまりXML構成ファイルがあることを認識しています)

上記のすべてのコンポーネントがコンパイル時に存在する必要がある場合に、この知識の「分離」を作成することのポイントは何ですか?

これは本当に私を悩ませています。おそらく私は完全に要点を逃しました。そうは言っても、多くの人が「テスト容易性」について話しているのを目にし、そこでの利点を見ることができますが、テストを窓の外に投げ出していると仮定しましょう。他にどのような利点がありますか?これは本当に私に何を与えていますか?

私はもともと、自分が構築しているアプリケーションの「プラグイン」パターンを設計するための良い方法を見つけることができることを期待して、この概念をさらに学ぶために探しました。これまでのところ、これはランタイムプラグインの概念では機能しないように見えます。

このテーマに関する洞察を楽しみにしています-ありがとうございます!

4

4 に答える 4

3

あなたのクラスを取り、DIを取り除きましょう。

public class SomeClass
{
    private Location _location = new Location();
    public SomeClass()
    {
    }
}

これで、Locationオブジェクトを作成でき、コンストラクターにパラメーターを取り込めません。コードはきれいに見えます、そしてそれは簡単でしたね?しかし、待ってください。Locationクラスに変更が加えられ、独自の依存関係であるLocationFinderが必要になります。それで、それをオブジェクト構築に追加し、コンストラクターに移動するかもしれません。

public class SomeClass
{
    private Location _location;
    public SomeClass()
    {
         _location = new Location(new LocationFinder());
    }
}

わかりました、あまりきれいではありませんが、それでもそれほど悪くはありません。ただし、6か月後には、LocationFinderを変更する必要があり、独自の依存関係を持つファクトリLocationFinderFactoryから作成する必要があります。

public class SomeClass
{
    private Location _location;
    public SomeClass()
    {
        var locationFinderFactory = new LocationFinderFactory(new LocationFinderStrategy());
        _location = new Location(locationFinderFactory.Create());
    }
}

それほどきれいではありませんか?さらに注目すべき点は、Locationの実装が変更されるたびに、SomeClassも変更する必要があることです。 SomeClassの実装をLocationと他の3つのクラスにも結合しました! これで、これら4つのクラスのいずれかを変更する必要があるたびにSomeClassを変更することになります。

話の教訓として、緩く結合された方法(DIの使用など)でクラスをコーディングすると、これらのタイプのコード変更は、影響を受けるはずのクラスのみにローカライズされます。

于 2013-03-21T22:12:57.803 に答える
2

依存性注入の最初の目標は、コードを簡単にユニットテストできるようにすることです。

次に、プロキシ(AOP、トランザクション、セキュリティチェックなどに使用)を挿入したり、挿入したコンポーネントを構成したり、プロファイルや構成に応じて実装を選択したりできるなど、追加の利点があります。これはすべて、あなたのフレームワーク。

于 2013-03-21T21:52:53.027 に答える
1

あなたが得ているのは、関心の分離です。DIを使用すると、を変更(または再コンパイル)するILogger ことなく、の実装を自由に変更したり、実装を交換したりできますSomeClass。DIでは、インターフェイス内のすべてのメソッドを実装している限り、SomeClassどのクラスがインターフェイスを実装しているかは関係ありません。ILogger具象クラスを使用した場合、メソッドを実装しているクラスを変更したい場合はSomeClass、同様に変更する必要があります。DIを使用すると、変更する必要があるのは、コンストラクターに送信されるクラス、またはIoCコンテナーの構成だけであり、それ自体を変更する必要はありませんSomeClass

于 2013-03-21T21:55:34.543 に答える
0

システム内の依存関係を管理する方法は、ソフトウェアの品質(柔軟性、堅牢性、再利用性、保守性)に大きな影響を与えます。特に、システムが時間の経過とともに多くの変更を行う場合、長期的には影響があります。そして、依存性注入は、依存性を管理するための(とりわけ)強力なツールの1つです。

この記事ではこのトピックについて美しく説明しているので、複製しようとはしません:) http://www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf

于 2013-03-21T22:04:27.960 に答える