Vendimi su contenitori IoC, per favore

17

Ho visto diversi consigliare l'uso di contenitori IoC nel codice. La motivazione è semplice. Prendi il seguente codice iniettato di dipendenza:

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
}

Into:

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>

(Quanto sopra è ipotetico esempio C ++ ovviamente)

Anche se sono d'accordo sul fatto che questo semplifica l'interfaccia della classe rimuovendo il parametro del costruttore di dipendenza, penso che la cura sia peggiore della malattia per un paio di motivi. Innanzitutto, e questo è un grosso problema per me, questo rende il tuo programma dipendente da un file di configurazione esterno. Se hai bisogno di una singola distribuzione binaria, semplicemente non puoi usare questi tipi di contenitori. Il secondo problema è che l'API ora è debolmente e peggio, stringly digitato. L'evidenza (in questo esempio ipotetico) è l'argomento della stringa sul contenitore IoC e il cast sul risultato.

Quindi .. ci sono altri vantaggi nell'utilizzare questo tipo di contenitori o non sono d'accordo con quelli che raccomandano i contenitori?

    
posta Billy ONeal 22.02.2011 - 17:54
fonte

3 risposte

12

In una grande applicazione con molti strati e molte parti mobili, sono gli svantaggi che cominciano ad apparire piuttosto secondari rispetto ai vantaggi.

Il contenitore "semplifica l'interfaccia" della classe, ma lo fa in un modo molto importante. Il contenitore è una soluzione al problema creato dall'integrazione delle dipendenze, che è la necessità di passare le dipendenze ovunque, attraverso i grafici degli oggetti e attraverso le aree funzionali. Qui c'è un piccolo esempio che ha una dipendenza - cosa succede se questo oggetto ha tre dipendenze e gli oggetti che dipendono da esso hanno più oggetti che dipendono da loro e così via? Senza un contenitore, gli oggetti nella parte superiore di queste catene di dipendenze diventano responsabili della traccia di tutte le dipendenze nell'intera applicazione.

Ci sono anche diversi tipi di contenitori. Non tutti sono scritti a caratteri stringenti, e non tutti richiedono file di configurazione.

    
risposta data 22.02.2011 - 18:57
fonte
4

Il framework Guice IoC da Java non si basa su un file di configurazione ma sul code di configurazione. Ciò significa che la configurazione è un codice non diverso dal codice che costituisce la tua applicazione effettiva e può essere refactored ecc.

Credo che Guice sia il framework IoC Java che finalmente ha ottenuto la configurazione giusta.

    
risposta data 22.02.2011 - 19:04
fonte
0

Questa fantastica risposta SO di Ben Scheirman descrive alcuni esempi di codice in C #; alcuni vantaggi dei contenitori IoC (DI):

  • La catena delle dipendenze può diventare nidificata e diventa rapidamente ingombrante da collegare manualmente.
  • Abilita l'uso di Programmazione orientata agli aspetti .
  • Dichiarante & transazioni di database nidificate.
  • Dichiarante & Unità di lavoro annidata
  • Registrazione.
  • Condizioni pre / post (Design by Contract).
risposta data 17.04.2012 - 09:27
fonte