Actualización: ¿Hay alguna manera de lograr lo que estoy tratando de hacer en un framework IoC distinto de Windsor? Windsor manejará bien los controladores, pero no resolverá nada más. Estoy seguro de que es mi culpa, pero sigo el tutorial textualmente y los objetos no se resuelven con la inyección de ctor, siguen siendo nulos a pesar de hacer los registros y resolverlos. Desde entonces, he descartado mi código DI y tengo la inyección manual por ahora porque el proyecto es sensible al tiempo. Esperando obtener DI resuelto antes de la fecha límite.Inyección de dependencia con la interfaz implementada por varias clases
tengo una solución que tiene varias clases que todos implementan la misma interfaz
Como un simple ejemplo, los Interface
public interface IMyInterface {
string GetString();
int GetInt();
...
}
Las clases concretas
public class MyClassOne : IMyInterface {
public string GetString() {
....
}
public int GetInt() {
....
}
}
public class MyClassTwo : IMyInterface {
public string GetString() {
....
}
public int GetInt() {
....
}
}
Ahora estas clases se inyectarán donde sea necesario en capas superiores a ellas como:
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
}
...
}
Ambos controladores se inyectan con la misma interfaz.
Cuando se trata de resolver estas interfaces con la clase concreta adecuada en mi COI, ¿cómo puedo diferenciar HomeController
que necesita una instancia de MyClassOne
y OtherController
necesita una instancia de MyClassTwo
?
¿Cómo puedo vincular dos clases concretas diferentes a la misma interfaz en el IoC? No quiero crear 2 interfaces diferentes ya que eso rompe la regla DRY y no tiene sentido de todos modos.
En el castillo de Windsor Me gustaría tener 2 líneas de este tipo:
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>());
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>());
Esto no va a funcionar porque yo sólo alguna vez obtener una copia de MyClassTwo
porque es el último registrado para la interfaz.
Como dije, no entiendo cómo puedo hacerlo sin crear interfaces específicas para cada concreto, haciendo eso no solo rompe las reglas DRY sino también el OOP básico. ¿Cómo logro esto?
Actualización basada en la respuesta de Mark Polsen
Aquí está mi actual COI, donde irían los .Resolve
declaraciones? Yo no ver nada en la documentación 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();
}
}
Usted puede unirse directamente a las clases concretas si es necesario. (bueno, al menos con Ninject puedes, pero no puedo imaginar que no puedas hacerlo con otras inmersiones.) – Buildstarted
No quieres hacer eso. Las dependencias de tus clases son ambiguas. No puede simplemente mirar una de las clases y decir que necesita una implementación específica. Recomiendo que use una fábrica como dependencia en ambas clases. Lea más aquí: http://www.codeproject.com/Articles/386164/Get-injected-into-the-world-of-inverted-dependenci – jgauffin
@jgauffin La promesa del método '.Named (...)' de Windsor es que puede resolver esa ambigüedad, pero en el uso real, no puedo hacer que Windsor resuelva nada :-( –