Un contenitore IoC influisce sulla progettazione di un'applicazione che utilizza l'iniezione di dipendenza?

4

È sicuro affermare che un Container è il "programma" o meccanismo che gestisce IoC tramite DI, ma in realtà non cambia il tuo progetto iniziale di DI realizzare un accoppiamento lento?

In altre parole, se voglio ottenere un accoppiamento lento, ad esempio per un Logger, l'utilizzo di un contenitore non lo cambia. Lo gestisce solo nel caso in cui avessi molte dipendenze per costruire una classe (meno tipizzazione, più gestibile, migliore test delle unità, ecc.)

Non cambierà il fatto che ho interfacce e contratti con ILogger o IDatabase, ad esempio, corretto?

//Assume I have to interfaces and two classes that implement them
Class DemoDI
{
    ILogger myLogger;
    IDatabase myDatabase;

    DemoDI(ILogger myLogger, IDatabase myDatabase)
    {
        this.myLogger = myLogger;
        this.myDatabase = myDatabase;
    }

    //Methods that do stuff with the logger and database
}

Sto chiedendo se questo non cambierebbe, quel modello di design. È solo che da qualche parte, (principale?), Vorrei (ad esempio con Unity)

ioc.RegisterType<ILogger MyLoggingClass>(new ContainerControlledLifetimeManager());
ioc.RegisterType<IDatabase MySQLDatabaseClass>; //transient by default

E, se MySQLDatabaseClass avesse,

interface IDatabaseConnection
{
    void GetConnection();
}
Class DataConnection : IDatabaseConnection
{

    public void GetConnection()
    {
        //Get a connection
    }

}
Class MySQLDatabaseClass
{
    DataConnection myConn;

    MySQLDatabaseClass(DataConnection myConn)
    {
        this.myConn = myConn;
        this.myConn.GetConnection();
    }
    //Do other things;


}

Quindi il contenitore lo avrebbe cablato anch'esso, assumendo che avessi un:

ioc.RegisterType<IDatabaseConnection, DataConnection>();

Altrimenti dovrei fare tutto a mano. Il contenitore è l'helper che lo rende bello e ordinato e assembla tutto.

Ora, se voglio Unit test la classe del database, dovrei solo aggiustare il mio contenitore:

ioc.RegisterType<IDatabase MyMockedUpMySQLDatabaseClass>; //transient by default

Comprendo correttamente lo scopo di un contenitore IoC? Spero di non essermi perso troppo nelle mie dipendenze.

    
posta johnny 22.12.2016 - 23:07
fonte

1 risposta

6

Is it safe to say that a Container is the "program" or mechanism that manages IoC via DI, but it doesn't really change your initial design of DI to accomplish loose coupling?

IoC e DI cambierà qualsiasi disegno che non li abbia seguiti in precedenza. L'utilizzo di un contenitore non dovrebbe modificare il design, ma spesso lo fa. Alcuni contenitori richiedono di diffondere la conoscenza del contenitore in tutto il codice base. Finisci per scambiare una serie di dipendenze con un'altra. Non dovresti essere in grado di guardare una classe e dire quale contenitore è coinvolto. Se puoi, ora sei dipendente da quel contenitore.

IoC e DI non richiedono un contenitore di gestione. Puoi gestirli al meglio comprendendo cosa sono piuttosto che aspettarti un contenitore per pensare. Puoi gestirli con un contenitore, ma è una tua scelta.

Foo foo = new Foo( new Bar() );

Quel giusto c'è un'iniezione di dipendenza. Foo dipende da Bar, o almeno da una specie di bar. Foo non può esistere senza di esso. Bar è una dipendenza. Poiché Bar è passato a Foo, Bar è una dipendenza che è stata iniettata.

IoC è un modo complicato per dire: non conoscere a fondo il codice di un'implementazione. Se Foo ha creato la propria Bar, Foo sarebbe stato codificato in modo rigido su Bar e Foo non poteva accettare nuovi tipi di Bar ma se Foo non sapeva di Bar, solo un'interfaccia, quindi la Barra può essere cambiata senza toccare Foo.

Ci sono molti modi per non codificare una dipendenza (seguire IoC):

  • Modello di fabbrica
  • Modello di localizzazione del servizio
  • Iniezione di dipendenza,
  • Iniezione del costruttore
  • Iniezione parametri
  • Iniezione setter
  • Iniezione interfaccia
  • Ricerca contestualizzata
  • Modello di progettazione del metodo di modello
  • Modello di progettazione della strategia

Puoi fare questa roba in un contenitore. Puoi farlo nel codice della costruzione. Puoi farlo in main.

Ovunque lo facciate, non mescolare questo codice di costruzione con un codice di comportamento. Cablaggi duri fanno da supporto al momento in cui si sente come se creasse il disordine che ha dato il via a questo movimento di contenitore esagerato, in primo luogo. È un vero problema. La soluzione migliore è capire che puoi aggiustarlo da solo.

    
risposta data 23.12.2016 - 06:19
fonte