Aggiornamento: C'è un modo per ottenere ciò che sto cercando di fare in un framework IoC diverso da Windsor? Windsor gestirà bene i controller ma non risolverà nient'altro. Sono sicuro che sia colpa mia, ma sto seguendo il tutorial verbatim e gli oggetti non si risolvono con l'iniezione di ctor, sono ancora nulli nonostante i registri e le risoluzioni. Da allora ho scartato il mio codice DI e ho fatto un'iniezione manuale perché il progetto è sensibile al fattore tempo. Sperando di ottenere che DI abbia funzionato prima della scadenza.Iniezione di dipendenza con interfaccia implementata da più classi
Ho una soluzione che dispone di più classi che tutto implementano la stessa interfaccia
Come semplice esempio, i Interface
public interface IMyInterface {
string GetString();
int GetInt();
...
}
Le classi concrete
public class MyClassOne : IMyInterface {
public string GetString() {
....
}
public int GetInt() {
....
}
}
public class MyClassTwo : IMyInterface {
public string GetString() {
....
}
public int GetInt() {
....
}
}
Ora queste classi saranno iniettate dove necessario in strati sopra di loro come:
public class HomeController {
private readonly IMyInterface myInterface;
public HomeController() {}
public HomeController(IMyInterface _myInterface) {
myInterface = _myInterface
}
...
}
public class OtherController {
private readonly IMyInterface myInterface;
public OtherController() {}
public OtherController(IMyInterface _myInterface) {
myInterface = _myInterface
}
...
}
Entrambi i controller vengono iniettati con la stessa interfaccia.
Quando si tratta di risolvere queste interfacce con la classe concreta corretta nel mio CIO, come faccio a differenziare che HomeController
ha bisogno di un'istanza di MyClassOne
e OtherController
ha bisogno di un'istanza di MyClassTwo
?
Come si collegano due diverse classi concrete alla stessa interfaccia in IoC? Non voglio creare 2 interfacce diverse in quanto interrompe la regola DRY e non ha comunque senso.
Nel Castello di Windsor avrei 2 righe come questo:
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>());
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>());
Questo non funzionerà perché sarò sempre e solo ottenere una copia di MyClassTwo
perché è l'ultimo registrato per l'interfaccia.
Come ho detto, non capisco come posso farlo senza creare interfacce specifiche per ogni concreto, facendo che si rompono non solo le regole ASCIUTATE ma anche l'OOP di base. Come ottengo questo?
Aggiornamento in base alla risposta di Mark Polsen
ecco la mia attuale CIO, dove sarebbe il .Resolve
dichiarazioni vanno? I don' vedere nulla nella documentazione Windsor
public class Dependency : IDependency {
private readonly WindsorContainer container = new WindsorContainer();
private IDependency() {
}
public IDependency AddWeb() {
...
container.Register(Component.For<IListItemRepository>().ImplementedBy<ProgramTypeRepository>().Named("ProgramTypeList"));
container.Register(Component.For<IListItemRepository>().ImplementedBy<IndexTypeRepository>().Named("IndexTypeList"));
return this;
}
public static IDependency Start() {
return new IDependency();
}
}
è possibile associare direttamente alle classi concrete, se necessario. (beh, almeno con Ninject puoi farlo ma non riesco a immaginare che non puoi farlo con altri cali.) – Buildstarted
Non vuoi farlo. Le dipendenze delle tue classi sono ambigue. Non puoi semplicemente guardare una delle classi e dire che ha bisogno di un'implementazione specifica. Raccomando di utilizzare una factory come dipendenza in entrambe le classi. Leggi di più qui: http://www.codeproject.com/Articles/386164/Get-injected-into-the-world-of-inverted-dependenci – jgauffin
@jgauffin La promessa del metodo '.Named (...) di Windsor è che può risolvere quell'ambiguità, ma nell'uso effettivo, non posso convincere Windsor a risolvere nulla :-( –