Castle Windsor: is there a way of validating registration without a resolve call?

巧了我就是萌 提交于 2019-12-03 09:34:59

问题


My current understanding of Castle Windsor registration is that one can only validate registration by calling Resolve on a root component. But since windsor's component model knows each component's dependencies, it should be possible to test that all dependencies can be satisfied without actually instantiating anything. The main reason for wanting to do this is to have a unit test for registration that doesn't require me to stub components that call external resources on start-up.

For example. I have a class Root that has a dependency on IChild:

public class Root : IRoot
{
    private IChild child;

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

If I register Root as IRoot, but don't register an IChild. When I call resolve like this:

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

container.Resolve<IRoot>();

I get an error:

MyNamespace.Root is waiting for the following dependencies: 

Services: 
- MyNamespace.IChild which was not registered. 

Is there something like:

container.TestResolve<IRoot>();

That would walk the dependency graph and check that all dependencies can be satisfied, but which doesn't actually instantiate anything?


回答1:


OK, It is possible. Thanks to Krzysztof Koźmic for showing me how. Not immediately obvious, but you can use Windsor's diagnostic subsystem to raise potential problems with registration. I've put together a little static method that throws if there are any misconfigured components:

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());
    }
}

You can use it like this:

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

CheckForPotentiallyMisconfiguredComponents(container);

In this case I get a MisconfiguredComponentException with this message:

'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.

See the castle documentation for more details on the diagnostic subsystem:

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



来源:https://stackoverflow.com/questions/8969973/castle-windsor-is-there-a-way-of-validating-registration-without-a-resolve-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!