Как я могу добиться этого в Виндзорском замке?(Миграция из StructureMap) - PullRequest
0 голосов
/ 23 октября 2011

Мне нужно изменить существующее веб-приложение, чтобы использовать Castle.Windsor в качестве контейнера IOC.Первоначально он был разработан с StructureMap.

Я застрял со следующей проблемой.

Допустим, я зарегистрировал пару интерфейсов и их соответствующих реализаций:

IFoo -> Foo
IBar -> Bar

Вызов container.Resolve<IFoo>() или container.Resolve<IBar>() работает просто отлично.Это означает, что службы зарегистрированы правильно.

У меня есть класс Web Api с зависимостями от других служб, таких как IFoo

public class BadRequestErrorHandler : HttpErrorHandler
{
    // services
    public BadRequestErrorHandler(IFoo foo) {...} // has dependency on IFoo
}

В StructureMap я могу позвонить:

var test = ObjectFactory.GetInstance<BadRequestErrorHandler>();

это разрешит зависимость IFoo.

Теперь это не работает с windsor.

Как этого достичь с помощью windsor?

Спасибо!

* РЕДАКТИРОВАТЬ * Я только смог заставить его работать, явно зарегистрировав BadRequestErrorHandler.

container.Register(Component.For<BadRequestErrorHandler>());

Я простонадеясь, что есть лучший способ добиться этого, который не требует регистрации классов с зависимостями.У меня их куча ...

* РЕДАКТИРОВАТЬ 2 **

Чтобы облегчить боль, я добавил специальный метод для работы с этими конкретными типами.

public T GetInstanceWithAutoRegister<T>()
{
    if (container.Kernel.GetHandler(typeof(T)) == null)
    {
        container.Register(Component.For<T>());
    }
    return container.Resolve<T>();
}

public object GetInstanceWithAutoRegister(Type pluginType)
{
    if (container.Kernel.GetHandler(pluginType) == null)
    {
        container.Register(Component.For(pluginType));
    }
    return container.Resolve(pluginType);
}

не идеально, но по крайней мере лучше, чем необходимость явной регистрации каждого типа.Надеюсь, у кого-то есть лучшее решение

1 Ответ

1 голос
/ 23 октября 2011

Вы можете достичь желаемого, зарегистрировав ILazyComponentLoader, который является ловушкой, которая вызывается Виндзором как «последнее средство», когда компонент не может быть разрешен.

В вашем случае реализация, вероятно, будет выглядеть примерно так:

public class JustLetWindsorResolveAllConcreteTypes : ILazyComponentLoader
{
    public IRegistration Load(string key, Type service)
    {
        return Component.For(service);
    }
}

- и тогда оно должно быть зарегистрировано так:

container.Register(Component.For<ILazyComponentLoader>()
         .ImplementedBy<JustLetWindsorResolveAllConcreteTypes>());

Подробнее об этом можно прочитать в документации .

...