Я пробую Ninject и модифицирую код, который написал с помощью Structure Map, чтобы увидеть, насколько это просто. В этом базовом коде у меня есть граф объектов, которые имеют разные конфигурации через реестры карты структуры, и тот, который будет использоваться, выбирается во время выполнения через значение в базе данных (в этом случае, чтобы вернуть тело службы wcf с некоторыми введенными объектами) . Так, например (используя код карты структуры):
Реестр 1 устанавливает все значения по умолчанию для типов IBusinessContext, IRules и ILogger. Это просто добавление типов GenericContext/Logger/Rules рядом с интерфейсами без какой-либо другой специализации.
public GenericRegistry()
{
// Set up some generic bindings here
For<ILogger>().Use<Loggers.GenericLogger>();
For<IBusinessRule>().Use<Rules.StandardRule>();
For<IBusinessContext>().Use<Contexts.GenericBusinessContext>();
For<ILoggerContext>().Use<Loggers.GenericLoggerContext>();
}
Реестр 2 настраивает IBusinessContext для использования класса SpecializedContext и указывает ctor использовать SpecializedLogger. Экземпляр для IBusinessContext называется SpecializedContext.
public SpecializedRegistry()
{
// Old style syntax as it affects the default for IBusinessContext
// Perhaps a hint at what I'm doing?
InstanceOf<IBusinessContext>().Is.OfConcreteType<Contexts.SpecializedBusinessContext>().Named(SpecializedInstanceName).Ctor<ILogger>().Is<Loggers.SpecialisedLogger>();
}
Все это работает, как и ожидалось в карте структуры (в зависимости от старого или нового синтаксиса).
Однако, когда я использовал Ninject, я столкнулся с проблемой, ожидая, что неназванный экземпляр будет использоваться по умолчанию (я понимаю, как работает Ninject). Это привело к некоторым исследованиям, которые все предположили, что использование именованных экземпляров — действительно плохая идея. Я понимаю, что есть лучшие способы сделать это, используя автоматическую регистрацию или атрибуты для установки имени или запроса определенного типа, но в системе, которую я описываю, должен быть способ во время выполнения выяснить, какую конфигурацию запрашивать. в верхней части дерева (и пусть инфраструктура IoC выясняет все остальное на основе зарегистрированных типов или правил).
Итак ... я просто неправильно использую концепцию IoC, ожидая запросить мой объект верхнего уровня по имени, или вообще есть лучший способ сделать то, что я пытаюсь сделать? Должен ли я вместо этого использовать что-то вроде MEF и относиться ко всему этому как к плагинам?
Я подчеркиваю, что я не использую это как тупую фабрику и не запрашиваю на каждом уровне кода экземпляр типа x из контейнера, это только инициирующее действие.
Заранее спасибо за ваше время и помощь :)