Widziałem kilka polecających użycie kontenerów IoC w kodzie. Motywacja jest prosta. Weź następujący wstrzyknięty kod zależności:
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
}
W:
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>
(Powyższe jest oczywiście hipotetycznym przykładem C ++)
Chociaż zgadzam się, że upraszcza to interfejs klasy poprzez usunięcie parametru konstruktora zależności, myślę, że lekarstwo jest gorsze od choroby z kilku powodów. Po pierwsze, i to jest dla mnie duży, to powoduje, że twój program zależy od zewnętrznego pliku konfiguracyjnego. Jeśli potrzebujesz pojedynczego wdrożenia binarnego, po prostu nie możesz używać tego rodzaju kontenerów. Drugi problem polega na tym, że interfejs API jest teraz słabo i gorzej, ściśle napisany. Dowodem (w tym hipotetycznym przykładzie) jest argument ciągu do kontenera IoC i rzut na wynik.
Więc ... czy są inne korzyści z używania tego rodzaju pojemników, czy też nie zgadzam się z tymi, którzy zalecają pojemniki?
źródło
Odpowiedzi:
W dużej aplikacji z wieloma warstwami i dużą ilością ruchomych części, wady zaczynają wyglądać na niewielkie w porównaniu z zaletami.
Kontener „upraszcza interfejs” klasy, ale robi to w bardzo ważny sposób. Kontener jest rozwiązaniem problemu, który powoduje wstrzykiwanie zależności, którym jest potrzeba przekazywania zależności w dowolnym miejscu, w dół przez wykresy obiektów i obszary funkcjonalne. Masz tutaj jeden mały przykład, który ma jedną zależność - co, jeśli ten obiekt miał trzy zależności, a obiekty, które od niego zależały, miały wiele obiektów, które zależały od nich , i tak dalej? Bez kontenera obiekty znajdujące się u góry tych łańcuchów zależności stają się odpowiedzialne za śledzenie wszystkich zależności w całej aplikacji.
Istnieją również różne rodzaje pojemników. Nie wszystkie z nich mają ciąg znaków i nie wszystkie wymagają plików konfiguracyjnych.
źródło
Struktura Guice IoC z Java nie polega na pliku konfiguracyjnym, ale na kodzie konfiguracyjnym . Oznacza to, że konfiguracja nie różni się kodem od kodu tworzącego twoją aplikację i może być refaktoryzowana itp.
Uważam, że Guice to platforma Java IoC, która w końcu poprawnie skonfigurowała.
źródło
Ta wspaniała odpowiedź Bena autorstwa Scheirmana zawiera szczegółowe przykłady kodu w języku C #; niektóre zalety kontenerów IoC (DI) to:
źródło