2015-06-12 1 views
2

У меня есть следующий код в моем приложении MVC, который отлично работает.Замок Виндзор, регистрирующий компоненты, соответствующие тем же услугам

container.Register(Component.For<CountryServiceBase>() 
    .ImplementedBy<CountryService>() 
    .LifestylePerWebRequest()); 

Виндзорский замок создает компонент

CountryService/CountryServiceBase 

Мой контроллер получает конкретизированных объект здесь:

public class MyController : MainController 
{ 
    public CountryServiceBase CountryService {get; set;} // instantiate by Ioc : OK 

Моя проблема заключается в том, что у меня есть много классов для регистрации. Таким образом, используя замок Виндзор я сделал следующее:

container.Register(
    Types 
    .FromAssemblyNamed("mynamespace") 
    .BasedOn(typeof(ServiceBase<>)) 
    .WithService.Base() 
    .LifestylePerWebRequest()); 

Виндзорский замок создает свои компоненты

CountryService/ServiceBase<Country> 
CountryServiceBase/ServiceBase<Country> 

Но мой MVC приложений ожидает CountryService/CountryServiceBase, и я не знаю, как указать, что замок Виндзор он может сопоставлять CountryServiceBase с CountryService, поскольку оба этих класса (один из них является абстрактным) наследует ServiceBase

Возможно ли это?

Примечание: Я опубликовал аналогичный вопрос, но мое исследование ведет к более точному, поэтому я удалил старый.

+0

Попробуйте изменить 'public CountryServiceBase CountryService {get; set;} 'by' public ServiceBase CountryService {get; set;} ' –

+0

Это будет работать, но в абстрактном классе CountryServiceBase у меня есть несколько объявленных методов. В противном случае это сработает. – AMS

+0

Возможно 'BasedOn (typeof (CountryServiceBase))'? –

ответ

0

Если CountryServiceBase класса является абстрактным, используя Classes вместо Types должен помочь избежать базового класса зарегистрирован (см here):

Классов с другой стороны, предварительно фильтруют типы рассматривать только неабстрактных классы

Однако это не выглядит, как вы можете избежать упоминания CountryServiceBase при регистрации, может быть, с помощью OrBasedOn(CountryServiceBase) тогда ваша реализация будет как и ServiceBase<>, так и CountryServiceBase.

0

Вы можете использовать отражение, чтобы получить все наследуемые классы из вашей базы данных. Вы можете найти способ сделать это here

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

+0

Это может быть идея. Я подожду, пока щедрость закончится, но мне нравится это решение, поскольку я мог бы добавлять сервисы, не регистрируя их один за другим, когда создаю их в своем проекте. – AMS

1

Обычно services являются интерфейсами. Вот почему AllInterfaces() работает для других.

Если вы проверяете API, вы найдете Select() метод, который легко использовать.

Если ни один из вышеперечисленных вариантов не подходит вам, вы можете предоставить собственную логику выбора в качестве делегата и передать его WithService.Select() метода.

Так регистрационный код может быть следующим:

container.Register(Types.FromThisAssembly() 
     .BasedOn(typeof(ServiceBase<>)) 
     .WithService.AllInterfaces() 
     .WithService.Select((t, b) => t.BaseType != null 
       ? new[] { t.BaseType } 
       : new Type[0]) 
     .LifestylePerWebRequest()); 

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

 Смежные вопросы

  • Нет связанных вопросов^_^