コードでIoCコンテナーを使用することをお勧めします。動機は簡単です。次の依存関係が挿入されたコードを見てください。
class UnitUnderTest
{
std::auto_ptr<Dependency> d_;
public:
UnitUnderTest(
std::auto_ptr<Dependency> d = std::auto_ptr<Dependency>(new ConcreteDependency)
) : d_(d)
{
}
};
TEST(UnitUnderTest, Example)
{
std::auto_ptr<Dependency> dep(new MockDependency);
UnitUnderTest uut(dep);
//Test here
}
に:
class UnitUnderTest
{
std::auto_ptr<Dependency> d_;
public:
UnitUnderTest()
{
d_.reset(static_cast<Dependency *>(IocContainer::Get("Dependency")));
}
};
TEST(UnitUnderTest, Example)
{
UnitUnderTest uut;
//Test here
}
//Config for IOC container normally
<Dependency>ConcreteDependency</Dependency>
//Config for IOC container for testing
<Dependency>MockDependency</Dependency>
(上記はもちろん架空のC++の例です)
これにより、依存関係コンストラクターパラメーターが削除され、クラスのインターフェイスが簡略化されることに同意しますが、いくつかの理由で、治療法は病気よりも悪いと思います。まず、これは私にとって大きな問題です。これにより、プログラムが外部構成ファイルに依存するようになります。単一のバイナリデプロイメントが必要な場合、これらの種類のコンテナを使用することはできません。 2番目の問題は、APIが弱くなり、悪いことにstringlyが入力されていることです。証拠(この架空の例では)は、IoCコンテナーへの文字列引数と、結果のキャストです。
それで、これらの種類のコンテナを使用することの他の利点はありますか、それともコンテナを推奨するそれらに同意しませんか?
多くのレイヤーと多くの可動部品を備えた大規模なアプリケーションでは、利点に比べてかなり軽微に見え始めるのが欠点です。
コンテナはクラスの「インターフェースを簡素化」しますが、非常に重要な方法でそうします。コンテナは、依存関係の注入によって発生する問題の解決策です。これは、依存関係をすべての場所、オブジェクトグラフ全体、および機能領域全体に渡す必要があることを意味します。ここに1つの依存関係を持つ1つの小さな例があります-このオブジェクトに3つの依存関係があり、それに依存するオブジェクトにthemに依存する複数のオブジェクトがある場合はどうでしょうか?コンテナーがない場合、これらの依存関係チェーンの最上位にあるオブジェクトは、アプリケーション全体のすべての依存関係を追跡する責任を負うことになります。
さまざまな種類のコンテナもあります。それらのすべてが文字列型であるわけではなく、すべてが構成ファイルを必要とするわけではありません。
JavaのGuice IoCフレームワークは構成ファイルに依存せず、構成codeに依存します。これは、構成が実際のコードを構成するコードと同じコードであることを意味しますアプリケーション、およびリファクタリングなどが可能.
私はGuiceがJava IoCフレームワークであり、ようやく構成が正しくなったと信じています。
この素晴らしい SO回答Ben Scheirman がC#のコード例を詳しく説明しています。 IoCコンテナー(DI)のいくつかの利点は次のとおりです。