Итак, я пытаюсь решить проблему, с которой, я уверен, уже столкнулся кто-то другой. По сути, я хочу, чтобы вызов моего контейнера IoC рекурсивно разрешал зависимости, но также потенциально мог выполнять некоторый пользовательский код для изменения результата на основе набора предопределенных критериев. Это расплывчато, поэтому позвольте мне привести пример:
Скажем, у меня есть контроллер вроде:
public class SampleController : Controller
{
protected SampleType _sampleType = null;
public SampleController(SampleType sampleType)
{
_sampleType = sampleType;
}
}
У меня также есть несколько тестовых версий этого контроллера (скажем, я его реорганизовал, и я хочу убедиться, что он не работает ужасно в Prod при тестировании AB его экспозиции):
public class SampleController_V2 : SampleController
{
protected SampleType _sampleType = null;
protected AnotherType _anotherType = null;
public SampleController_V2(SampleType sampleType, AnotherType anotherType)
{
_sampleType = sampleType;
_anotherType = anotherType;
}
}
Я расширил DefaultControllerFactory
для использования Unity при создании контроллеров. Это все работает нормально. Теперь, что я хочу сделать, это дает возможность AB протестировать любой конкретный тип в иерархии, если что-то разрешить. Это хорошо работает для верхнего уровня, но не для дочерних элементов, так как повторяется через граф объектов.
Прямо сейчас, он выберет соответствующий контроллер для разрешения и предоставит ему свои зависимости. Тем не менее, я не могу перехватить отдельные вызовы зависимостей, чтобы также проверить их AB. Я могу определить тест с помощью конфигурации базы данных, а затем разрешить контейнеру IOC на основе критериев. Пример:
SessionIds that start with the letter 'a': SampleController_V2
Everyone Else : SampleController
UserIds ending in 9 : SampleType_V2
Everyone Else : SampleType
Это все работает для элемента верхнего уровня. Однако вызов _unityContainer.Resolve(type)
не кажется рекурсивным вызовом; Я хотел бы иметь возможность внедрить этот код в любой момент, когда он пытается разрешить тип:
-> Attempt to Resolve SampleController
-> Test Code Tells Us to use _V2 if possible.
-> Attempt to Resolve SampleType
-> Test Code tells us to use the _V1 if possible.
-> Resolves SampleType_V1
-> Attempt to Resolve AnotherType
-> No Test Defined, Use the Default
-> Resolves AnotherType
-> Resolves SampleController_V2 (passing SampleType_V1 as the dependency and then AnotherType as the other dependency)
Просматривая некоторые онлайн-статьи, кажется, что мне нужно использовать какой-то перехватчик Unity, но сейчас я почти пишу свой собственный контейнер IoC с какой-то встроенной архитектурой тестирования.
Надеюсь, у кого-то есть хорошая идея, как это сделать, прежде чем я начну мучиться с поиском конструктора, а затем рекурсивным разрешением каждого типа.
РЕДАКТИРОВАТЬ: Таким образом, на самом деле оказалось не так уж и ужасно создавать свои собственные инъекции, рекурсивно проверяя параметры конструктора каждой зависимости, но я думаю, что начальство может немного встревожиться, если я выброшу Unity для моего собственного обычая. решение.