È 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.