Castle Windsor: автоматическая регистрация типов из одной сборки, реализующих интерфейсы из другой

В качестве контейнера IoC я использую Castle Windsor. У меня есть приложение, которое имеет структуру, похожую на следующую:

  • MyApp.Services.dll
    • IEmployeeService
    • IContractHoursService
    • ...
  • MyApp.ServicesImpl.dll
    • EmployeeService : MyApp.Services.IEmployeeService
    • ContractHoursService : MyApp.Services.IContractHoursService
    • ...

В данный момент я использую конфигурацию XML, и каждый раз, когда я добавляю новую пару IService/Service, мне приходится добавлять новый компонент в файл конфигурации XML. Я хочу переключить все это на свободный API регистрации, но пока не выработал правильный рецепт, чтобы делать то, что я хочу.

Кто-нибудь может помочь? Все образы жизни будут singleton,

Спасибо заранее.

2 ответа

Решение

С AllTypes Вы можете легко сделать это:

С http://stw.castleproject.org/(S(nppam045y0sdncmbazr1ob55))/Windsor.Registering-components-by-conventions.ashx:

Регистрация компонентов по одному может быть очень повторяющейся работой. Также не забывая регистрировать каждый новый тип, который вы добавляете, может быстро привести к разочарованию. К счастью, вам не обязательно делать это, по крайней мере, всегда. Используя класс ввода AllTypes, вы можете выполнять групповую регистрацию типов на основе определенных вами указанных характеристик.

Я думаю, что ваша регистрация будет выглядеть так:

AllTypes.FromAssembly(typeof(EmployeeService).Assembly)
    .BasedOn<IEmployeeService>()
    .LifeStyle.Singleton

Если вы реализуете базовый тип, как IService на ваших интерфейсах вы можете зарегистрировать их все сразу, используя следующую конструкцию:

AllTypes.FromAssembly(typeof(EmployeeService).Assembly)
    .BasedOn<IService>()
    .WithService.FromInterface()
    .LifeStyle.Singleton

Дополнительные примеры смотрите в статье. Это очень хорошее описание возможностей.

Я немного поняла ответ Питера (главное, как он предположил, AllTypes) и придумали это:

// Windsor 2.x
container.Register(
    AllTypes.FromAssemblyNamed("MyApp.ServicesImpl")
    .Where(type => type.IsPublic)
    .WithService.FirstInterface()
    );

Это проходит через все публичные занятия в MyApp.ServicesImpl.dll сборка и регистрирует каждый в контейнере, используя первый интерфейс, который он реализует. Поскольку мне нужны все классы в сборке служб, мне не нужен интерфейс маркера.

Вышесказанное работает для старой версии Windsor. В текущей документации Castle Windsor для регистрации компонентов для последней версии предлагается следующее:

// Windsor latest
container.Register(
    AllTypes.FromAssemblyNamed("MyApp.ServicesImpl")
    .Where(type => type.IsPublic) // Filtering on public isn't really necessary (see comments) but you could put additional filtering here
    .WithService.DefaultInterface()
    );
Другие вопросы по тегам