2012-01-23 15 views
19

Mi comprensión actual del registro de Castle Windsor es que uno solo puede validar el registro llamando a Resolver en un componente raíz. Pero dado que el modelo de componente de windsor conoce las dependencias de cada componente, debería ser posible probar que todas las dependencias se pueden satisfacer sin instanciar realmente nada. La razón principal para querer hacer esto es tener una prueba unitaria para el registro que no requiera que reste componentes que llaman a recursos externos en la puesta en marcha.Castle Windsor: ¿hay alguna manera de validar el registro sin una decisión?

Por ejemplo. Tengo una raíz clase que tiene una dependencia en iChild:

public class Root : IRoot 
{ 
    private IChild child; 

    public Root(IChild child) 
    { 
     this.child = child; 
    } 
} 

Si registro Root como IRoot, pero no registro un iChild. Cuando llamo a la resolución de esta manera:

var container = new WindsorContainer().Register(
    Component.For<IRoot>().ImplementedBy<Root>() 
    ); 

container.Resolve<IRoot>(); 

consigo un error:

MyNamespace.Root is waiting for the following dependencies: 

Services: 
- MyNamespace.IChild which was not registered. 

¿Hay algo así como:

container.TestResolve<IRoot>(); 

Eso sería recorrer el grafo de dependencias y comprobar que todas las dependencias pueden estar satisfecho, pero que en realidad no instancia nada?

Respuesta

27

OK, es posible. Gracias a Krzysztof Koźmic por mostrarme cómo. No es inmediatamente obvio, pero puede usar el subsistema de diagnóstico de Windsor para plantear posibles problemas con el registro. He creado un pequeño método estático que lanza si hay algún mal configurados componentes:

private static void CheckForPotentiallyMisconfiguredComponents(IWindsorContainer container) 
{ 
    var host = (IDiagnosticsHost)container.Kernel.GetSubSystem(SubSystemConstants.DiagnosticsKey); 
    var diagnostics = host.GetDiagnostic<IPotentiallyMisconfiguredComponentsDiagnostic>(); 

    var handlers = diagnostics.Inspect(); 

    if (handlers.Any()) 
    { 
     var message = new StringBuilder(); 
     var inspector = new DependencyInspector(message); 

     foreach (IExposeDependencyInfo handler in handlers) 
     { 
      handler.ObtainDependencyDetails(inspector); 
     } 

     throw new MisconfiguredComponentException(message.ToString()); 
    } 
} 

Se puede utilizar la siguiente manera:

var container = new WindsorContainer().Register(
    Component.For<IRoot>().ImplementedBy<Root>() 
    ); 

CheckForPotentiallyMisconfiguredComponents(container); 

En este caso me sale un MisconfiguredComponentException con este mensaje:

'WindsorSpikes.Root' is waiting for the following dependencies: 
- Service 'WindsorSpikes.IChild' which was not registered. 

WindsorSpikes.MisconfiguredComponentException: 
'WindsorSpikes.Root' is waiting for the following dependencies: 
- Service 'WindsorSpikes.IChild' which was not registered. 

Consulte la documentación del castillo para más detalles sobre el subsistema de diagnóstico:

http://stw.castleproject.org/Default.aspx?Page=Debugger-views&NS=Windsor

+0

agradable método de ensayo :) – bevacqua

+1

este código ya no compila: El tipo 'Castle.Windsor.Diagnostics.IPotentiallyMisconfiguredComponentsDiagnostic' no se puede utilizar como parámetro de tipo 'TDiagnostic' en el tipo genérico o método 'Castle.Windsor .Diagnostics.IDiagnosticsHost.GetDiagnostic () '. No hay conversión de referencia implícita de 'Castle.Windsor.Diagnostics.IPotentiallyMisconfiguredComponentsDiagnostic' a 'Castle.Windsor.Diagnostics.IDiagnostic '. ¿Sabes cómo solucionarlo? –

+0

Peri, el código compila para mí, Castle 3.2 en .net 4 – samy

Cuestiones relacionadas