Windsor Ioc Service Overrides: для данного ключа уже зарегистрирован компонент - PullRequest
4 голосов
/ 22 октября 2011

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

Я прочитал это http://docs.castleproject.org/Windsor.Registering-components-one-by-one.ashx#Supplying_the_component_for_a_dependency_to_use_Service_override_9

и спросил это вчера Виндзорский контейнер Ioc: как зарегистрировать, что определенные конструкторы используют разные реализации интерфейса

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

например

У меня есть 2 контроллера MVC.Один для регистрации и один для карточных платежей.Ведение журнала принимает провайдер, который, в свою очередь, берет IService.Контроллер CardPayment принимает поставщика платежных карт, который, в свою очередь, принимает услугу IService.Поставщик платежной карты должен получить безопасную услугу, а провайдер регистрации - обычную услугу

код указан ниже:

Регистрации:

Component.For<ILoggingProvider>().ImplementedBy<LoggingProvider>(),
Component.For<ICardPaymentProvider>().ImplementedBy<CardPaymentProvider>(),
Component.For<IService>().ImplementedBy<WebService>().Named("default"),
Component.For<IService>().ImplementedBy<SecureWebService>().Named("secure"),
Component.For<CardPaymentProvider>().ServiceOverrides(ServiceOverride.ForKey("service").Eq("secure")),
Component.For<LoggingProvider>().ServiceOverrides(ServiceOverride.ForKey("service").Eq("default"))

Иерархия классов:

 public LoggingController(ILoggingProvider loggingProvider)
 {
            this.loggingProvider = loggingProvider;
 }

 public CardPaymentController(ICardPaymentProvider cardPaymentProvider)
{
            this.cardPaymentProvider = cardPaymentProvider;
}

    public interface IService
    {
        void Doit();
    }
    public class WebService : IService
    {
        public void Doit()
        {
            throw new NotImplementedException();
        }
    }
    public class SecureWebService : IService
    {
        public void Doit()
        {
            throw new NotImplementedException();
        }
    }
    public class CardPaymentProvider : ICardPaymentProvider
    {
        private readonly IService service;
        public CardPaymentProvider(IService service)
        {
            this.service = service;
        }
    }
    public interface ICardPaymentProvider
    {
    }
    public class LoggingProvider : ILoggingProvider
    {
        private readonly IService service;
        public LoggingProvider(IService service)
        {
            this.service = service;
        }
    }
    public interface ILoggingProvider
    {
    }

При запуске выдается ошибка

"Для данного ключа уже зарегистрирован компонент Spike.CardPaymentProvider"

Если я добавлю Named ("somename ") либо для регистрации CardPaymentProvider, либо для регистрации ICardPaymentProvider, затем она запускается нормально, но не обеспечивает безопасную реализацию службы для CardPaymentProvider - просто обычная версия

, чтоя делаю не так?

1 Ответ

2 голосов
/ 22 октября 2011

Вы должны определить переопределения службы в той же регистрации. Вместо:

Component.For<ICardPaymentProvider>().ImplementedBy<CardPaymentProvider>(),
Component.For<CardPaymentProvider>().ServiceOverrides(ServiceOverride.ForKey("service").Eq("secure")),

сделать:

Component.For<ICardPaymentProvider>()
         .ImplementedBy<CardPaymentProvider>()
         .ServiceOverrides(ServiceOverride.ForKey("service").Eq("secure")),
...