2012-04-11 10 views
5

Tenemos una solución con múltiples proyectos que representan las capas de nuestra aplicación. p.¿Es posible que Castle Windsor resuelva dependencias de propiedad cuando no tiene una referencia al contenedor?

dominio

datos

lógica

WebUI

contenedor Nuestro castillo de Windsor está referenciado de nuestra capa de tela y luego en cascada estas dependencias a través de nuestras capas. Por ejemplo ...

// In Domain 
public interface IFooRepository 
{ 
    void DoSomething(); 
} 

// In Data 
public class FooRepository : IFooRepository 
{ 
    public void DoSomething() 
    { 
     // Something is done 
    } 
} 

// In Logic 
public class MyThingManager 
{ 
    private readonly IFooRepository fooRepository; 

    public MyThingManager(IFooRepository fooRepository) 
    { 
     this.fooRepository = fooRepository; 
    } 

    public void AMethod() 
    { 
     this.fooRepository.DoSomething(); 
    } 

} 

// In Web 
// in some controller.... 
var newManager = new MyThingManager(WindsorContainer.Resolve<IFooRepository>()); 
newManager.DoSomething(); 

y esto funciona bien hasta que nuestros gerentes tengan muchos miembros que tengan sus propias dependencias. Cuando esto sucede, terminamos resolviendo tanto las dependencias de los gerentes como las dependencias de las dependencias y las conectamos en cascada desde la capa web. Este resultado es algunos constructores bastante grandes.

¿Hay una forma más elegante de, por ejemplo, que los componentes internos de un administrador resuelvan sus propias dependencias sin tener acceso al contenedor?

Tenga en cuenta que SOLAMENTE la capa web tiene acceso al contenedor (para evitar una dependencia circular del proyecto), solo la capa web puede activar WindsorContainer.Resolve() la capa lógica no puede ser la única forma de cascada una dependencia sin la asistencia de contenedores era resolverlo en la capa web y luego pasarlo por la cadena utilizando su interfaz.

+2

"terminamos resolviendo las dependencias de los gerentes y sus dependencias y las conectando en cascada desde la capa web". No entiendo esto. Cuando utiliza la inyección de constructor y permite que el contenedor inyecte automáticamente las dependencias en el constructor de un tipo, no debería haber ningún problema. Mostrar un poco más de código visualizando este problema podría ser útil. – Steven

Respuesta

6

La respuesta corta es que cada vez que vea .Resolve<T> es probable que doing it wrong. Como @Steven mencionó, usted quiere usar las funciones incorporadas de Windsor para proporcionarle inyección de constructor (y/o inyección de propiedad). Esto significa que WindsorContainer necesita saber el objeto que está en la raíz de su gráfico de objetos.

En su caso, caminaría por el árbol de objetos (desde MyThingyManager) hasta llegar al objeto raíz. Por ejemplo, en una aplicación ASP.NET MVC, este sería el controlador que contiene la acción a la que se llama. Para el caso de MVC3, usaría un DependencyResolver para iniciar la inyección de todas las dependencias.

Además, lo que he encontrado útil con Windsor en el pasado es tener un instalador diferente por componente (ensamblaje). Y luego registre estos instaladores en la base del proceso que aloja la aplicación.

Así que en cada componente que tendría un instalador como:

public class Installer : IWindsorInstaller 
{ 
     public void Install(Castle.Windsor.IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store) 
     { 
      container.Register(
       Component.For<IMyThingManager>().ImplementedBy<MyThingManager>(), 
       Component.For<IFooRepository>().ImplementedBy<FooRepository>() 
       ); 
     } 
} 

Y luego en el Global.asax.cs Application_Start que tendría algo como:

var container = new WindsorContainer(); 
container.Install(FromAssembly.This()); 
container.Install(FromAssembly.Containing(typeof(ComponentThatContains.MyThingManager.Installer))); 

Esto le da una forma para gestionar todas las dependencias en todo el gráfico de objetos y resolverlas mediante la inyección de constructores. Espero que esto ayude.

+0

Gracias por esto, comenzó un replanteamiento completo de cómo hacemos el COI y ahora funciona como magia: D –

+0

Me alegro de poder escuchar, me alegro de poder ayudar. –

Cuestiones relacionadas