2016-06-13 3 views
1

Это частично дублирование того же вопроса, на который еще не ответил. См. Здесь: How can I override a component registered in Castle Windsor?Переопределение регистрации компонентов в замке Виндзор? Какой контейнер поддерживает его?

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

Имейте в виду, что:

  1. Я не хочу, чтобы создать новый контейнер.
  2. Мне все равно, если контейнеры не должны использоваться для модульных испытаний.
  3. Я не хочу использовать производные контейнеры.

Если Castle Windsor не может предоставить эту простую функциональность, какую другую реализацию контейнера вы бы порекомендовали?

+0

Я считаю, что ваша проблема возникает из двух ваших «ограничений» - №1 и №2. Если вы действительно тестируете * unit *, то контейнер будет просто мешать вам, у вас есть одна часть * кода под тестированием *, и все ваши зависимости должны быть издевались. Если вы тестируете * интеграцию *, тогда может иметь смысл использовать контейнер. Но в этом случае * вы должны использовать другой контейнер, чем ваше приложение *, и высмеивать все, что не имеет отношения к тесту. [Повторное использование контейнера] (http://blog.ploeh.dk/2015/01/06/composition-root-reuse/) немного напоминает повторное использование файла .config для другого приложения - зачем вам? – NightOwl888

+1

@ NightOwl888: Это должно использоваться для тестов интеграции. Новый контейнер не имеет смысла, например, Я хотел бы проверить все, кроме компонента log4net. Или все, кроме уровня доступа к БД. Если я создаю новый контейнер, я не тестирую реальную тему, а что-то еще, что не является точкой. Копирование/вставка кода сопоставления контейнеров также не является наилучшей практикой (часто наблюдаемой). –

+0

Возможный дубликат [Как я могу переопределить компонент, зарегистрированный в Castle Windsor?] (Http://stackoverflow.com/questions/1687574/how-can-i-override-a-component-registered-in-castle-windsor) –

ответ

0

Ответ на вторую часть вопроса - какие контейнеры поддерживают регистрацию.

Ninject.

См. Методы Bind()/Unbind().

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

1

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

Но я думаю, что вы должны пересмотреть немного свой дизайн:

  1. Почему ваш класс нужен прямой доступ к контейнеру и попытаться решить из него само по себе?
  2. Зачем вам нужно изменить исходный код для тестового кода? Если вы пишете чистый код инъекции в зависимости от SOLID, ваши тесты будут действительно «волшебным» потоком.

Не могли бы вы подробнее рассказать о дизайне и соответствующих классах?

1

Windsor работает с соглашением, что «последняя регистрация выигрывает». Но, если вы НЕ СПЕЦИАЛЬНО сказали, что этот компонент будет переопределен, он будет генерировать исключение. Таким образом, существует 3 способа переопределения существующего компонента:

  1. Зарегистрировать компонент с .IsDefault(). Это переопределит существующую регистрацию.
  2. Зарегистрируйте компонент с .IsFallback(). Это позволит компоненту переопределить позже.
  3. Использование уникального имени для компонента - .Named ("NewComponentName").

Я лично предпочитаю.IsDefault() и используйте это сокращенное расширение в моих интеграционных тестах:

public static class WindsorContainerExtensions 
    {    
     public static void Override<TService>(this IWindsorContainer container, TService instance) where TService : class 
     { 
      container.Register(Component.For<TService>().Instance(instance).IsDefault()); 
     } 
    } 
+0

IsFallback и IsDefault кажутся своего рода решением. Плохая вещь об этом, что вам нужно изменить испытуемый предмет, то есть вам нужно зарегистрировать свои компоненты определенным образом, чтобы их можно было протестировать позже. В конце концов я пошел с Ninject и его функциональностью Bind/Unbind. У Виндзора, похоже, не хватает базовой функциональности, поэтому я должен был принять это решение. –

+0

Вам не нужно менять тему, подлежащую тестированию. .IsDefault() используется в модульных тестах, когда вы не хотите заменять компонент. – andree

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