Подтвердить что ты не робот

Castle Windsor: существует ли способ подтверждения регистрации без разрешения?

Мое настоящее понимание регистрации Castle Windsor заключается в том, что можно только подтвердить регистрацию, вызвав Resolve на корневой компонент. Но поскольку модель компонента Windsor знает зависимости каждого компонента, должно быть возможно проверить, что все зависимости могут быть выполнены без фактического создания каких-либо объектов. Основная причина для этого - иметь unit test для регистрации, которая не требует, чтобы я заглушил компоненты, которые вызывают внешние ресурсы при запуске.

Например. У меня есть класс Root, который имеет зависимость от IChild:

public class Root : IRoot
{
    private IChild child;

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

Если я зарегистрирую Root как IRoot, но не регистрирую IChild. Когда я вызываю так:

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

container.Resolve<IRoot>();

Я получаю сообщение об ошибке:

MyNamespace.Root is waiting for the following dependencies: 

Services: 
- MyNamespace.IChild which was not registered. 

Есть ли что-то вроде:

container.TestResolve<IRoot>();

Это будет ходить по графику зависимостей и проверять, что все зависимости могут быть удовлетворены, но который на самом деле не создает каких-либо экземпляров?

4b9b3361

Ответ 1

ОК, это возможно. Благодаря Krzysztof Koźmic за то, что он показал мне, как это сделать. Не сразу очевидно, но вы можете использовать диагностическую подсистему Windsor для выявления потенциальных проблем с регистрацией. Я собрал небольшой статический метод, который бросает, если есть какие-то неправильно сконфигурированные компоненты:

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

Вы можете использовать его следующим образом:

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

CheckForPotentiallyMisconfiguredComponents(container);

В этом случае я получаю MisconfiguredComponentException с этим сообщением:

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

Более подробную информацию о диагностической подсистеме см. в документации к замку:

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