In generale, le mie dipendenze sono astratte alle interfacce, ma userò solo un'implementazione concreta durante l'utilizzo non di test. Ad esempio, se io scrivo un FooService
:Iniezione di dipendenza: cosa si perde quando si istanziano le classi concrete nel costruttore senza parametri
public class FooService : IFooService
{
private readonly IBarDependency _barDependency;
public FooService(IBarDependency barDependency)
{
this._barDependency = barDependency;
}
public FooService() : this (new BarDependency())
{
// nothing to do here
}
. . . // code goes here
}
Ora puristi tendono a boccheggiare per l'orrore, perché ho istanziato una classe concreta nel costruttore senza parametri. In passato, l'ho scrollato di dosso, perché so che l'unica volta in cui non userò la lezione concreta è quando collaudo unità e dipendenze beffarde.
Mentre lo fa paio classe FooService
alla classe BarDependency
, non è uno stretto accoppiamento; queste classi e interfacce esistono anche nello stesso assembly, quindi non mi sembra che io stia perdendo molto qui o dipingendo me stesso in un angolo. Posso ancora facilmente testare la classe FooService
senza ottenere codice ingestibile, semplicemente usando il costruttore che mi permette di passare in interfacce fittate.
Quindi la domanda è: che cosa è effettivamente a rischio qui? Cosa sto perdendo con questo tipo di schema che vale la pena aggiungere un contenitore IoC?
Io uso lo stesso approccio in piccoli progetti. DI e altre regole del "fare bene" di solito rendono i piccoli progetti eccessivamente complessi. Certo, porta molti vantaggi ma non vale sempre la pena. –