2

私は依存性注入を学ぼうとしていますが、まだ把握していない微妙な点がたくさんあります。そのために読み始めた本の 1 つに、Karl Seguin 著のFoundations of Programming」があります。依存性注入に関する例があります:

public class Car
{
    private int _id;

    public void Save()
    {
        if (!IsValid())
        {
            //todo: come up with a better exception
            throw new InvalidOperationException("The car must be in a valid state");
        }

        IDataAccess dataAccess = ObjectFactory.GetInstance<IDataAccess>();
        if (_id == 0)
        {
            _id = dataAccess.Save(this);
        }
        else
        {
            dataAccess.Update(this);
        }
    } 
}

ObjectFactoryそして、メソッド内で直接呼び出すのではなく、別のレベルの間接化を追加することを提案します。

public static class DataFactory
{
    public static IDataAccess CreateInstance
    {
        get
        {
            return ObjectFactory.GetInstance<IDataAccess>();
        }
    }
}

しかし、これは実際には「サービスの場所」ではありませんか?

4

3 に答える 3

2

サービスロケーターです。依存関係を使用するには、いくつかの方法があります。

  • 集計(事例)

  • 構成

    • コンストラクターの DI、必須 (上位レベルで SL を使用して注入できます)

    • プロパティの DI、オプション (上位レベルで SL を使用して注入できます)

何を選択するかは、依存関係が安定しているか不安定であるか、テストでモックする必要があるかどうかなど、多くの要因によって異なります。Mark Seemann による 'Dependency Injection in .NET' という DI に関する優れた本があります。

于 2013-02-06T19:32:46.700 に答える
1

あなたの例はServiceLocatorです。どこかに常にServiceLocatorがあります。重要なのは、なぜそれを直接使用するのか、そしてなぜ理想的には使用する必要がないのかを理解することです。

重要な概念は、依存性逆転の原則です。依存性の注入と制御の反転は、プリンシパルの適用を容易にするツールです。理想的には、オブジェクトコンストラクターパラメーターを、オブジェクト作成時に解決されるインターフェイス定義にする必要があります。

asp.net MVCなどの最新のツールを使用している場合は、アプリケーションのエントリポイントであるコンポジションルートと呼ばれるものにアクセスできます。MVCではそれはコントローラーです。コンポジションルートにアクセスできるので、ServiceLocatorを使用する必要はありません。これは、登録してセットアップしたIOCフレームワークによってインジェクションが上から駆動されるためです。基本的に、コントローラーには、IOCに登録され、コントローラーインスタンスの作成時に自動的に挿入されるISomeServiceなどのコンストラクターパラメーターがあります。ISomeServiceにいくつかの依存関係がある場合、オブジェクトがどんどん深くなるにつれて、それらはISomeUtilityとしてコンストラクターにも含まれます。これは理想的であり、オブジェクトを解決するためにServiceLocatorを使用する必要はありません。

ルートへのアクセスを許可しないテクノロジーを使用している状況にある場合、またはルートがないアプリケーションでIOCフレームワークの使用を開始したい場合で、IOCフレームワークを初めて追加する場合は、コンポジションルートに到達できないことがわかります。フレームワークまたはコードの品質の制限である可能性があります。このような場合、ServiceLocatorを使用するか、自分でオブジェクトを直接作成する必要があります。このような場合、ServiceLocatorを使用しても問題はなく、そのオブジェクトを自分で作成するよりも優れています。

于 2013-02-06T20:53:05.797 に答える
1

はい、私にはSLに見えます。依存性注入は、伝統的に 2 つのパターンのいずれかに従います。プロパティ注入またはコンストラクター注入。

依存性注入は、最初はサービス ロケーションよりも手間がかかるように感じますが、サービス ロケーション (SL) には多くの欠点があります。サービスロケーターを使用すると、気まぐれにサービスを要求するのは簡単すぎます。これは、リファクタリングしてカップリングが「高すぎる」ことに気付くまでは問題ありません。

DI では、誰が何を必要としているかを前もって考える必要があるため、コンストラクター インジェクション形式を好みます。

とは言うものの、私の現在のプロジェクトは、サービス ロケーターを使用したグリーン フィールド プロジェクトとして開始されました。それは、依存関係について考えずに、アプリケーションの形を進化させるという柔軟性を与えてくれたからです。最近、私は DI を使用するようにリファクタリングしています。主に、何が何に、なぜ依存しているかを把握するためです。

于 2013-02-06T19:23:20.140 に答える