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

145
10

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


    MyApp.Services.dll
      IEmployeeService
      IContractHoursService
      ...

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

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


Может ли кто-нибудь помочь? Стиль жизни будет singleton.


Большое спасибо заранее.

спросил(а) 2021-01-25T17:09:18+03:00 4 месяца, 3 недели назад
1
Решение
162

С помощью 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

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

ответил(а) 2021-01-25T17:09:18+03:00 4 месяца, 3 недели назад
88

Я принял Pieter answer чуть-чуть (ключ, как он предложил, 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()
);

ответил(а) 2021-01-25T17:09:18+03:00 4 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема