Мы создаем приложение, которое имеет ряд точек интеграции с другими системами. Мы эффективно используем Unity для всех наших потребностей в инъекциях зависимостей. Весь бизнес-уровень был построен с использованием интерфейса, основанного на интерфейсе, причем фактическая реализация была внедрена во внешний корневой состав во время загрузки приложения.Абстрактная фабрика вписывается в Unity
Мы хотели обработать слой интеграции элегантным образом. Бизнес-классы и репозитории зависят от интерфейсов IIntegrationController<A, B>
. Несколько реализаций IIntegrationController<A, B>
представляют собой интеграцию с одной целевой системой в фоновом режиме - формирование слоя интеграции. В настоящее время мы соединяем все в корне композиции, одним выстрелом, в начале. Потребители этого интерфейса также регистрируются с соответствующими InjectionConstrutor
и ResolvedParameter
спереди. Большинство типов работают с PerResolveLifetime
, а бизнес-классы, потребляющие IIntegrationController
, также разрешаются для каждого контекста запроса отдельно.
См. Нижеприведенный код.
// IIntegrationController Family 1
// Currently the default registration for IIntegrationController types injected into the business classes
container.RegisterType<IIntegrationController<A, B>, Family1-IntegrationController<A, B>>();
container.RegisterType<IIntegrationController<C, D>, Family1-IntegrationController<C, D>>();
// IIntegrationController Family 2 (currently not registered)
// We want to be able to register this, or manage this set of mapping registrations separately from Family 1,
// and be able to hook these up dynamically instead of Family-1 on a per-resolve basis
container.RegisterType<IIntegrationController<A, B>, Family2-IntegrationController<A, B>>();
container.RegisterType<IIntegrationController<C, D>, Family2-IntegrationController<C, D>>();
// Repository/Business Class that consume IIntegrationControllers.
// There is a whole family of IIntegrationController classes being hooked in,
// and there are multiple implementations for the family (as shown above). A typical AbstractFactory scenario.
container.RegisterType(typeof(Repository<Z>), new PerResolveLifetimeManager(),
new InjectionConstructor(
new ResolvedParameter<IIntegrationController<A, B>>(),
new ResolvedParameter<IIntegrationController<C, D>>())
);
Постановка задачи:
Мы хотим, возможность переключать всю семью IIntegrationController<A, B>
во время выполнения. Когда бизнес-класс решается, мы хотим, чтобы он был введен с правильной версией IIntegrationController<A, B>
на основе параметра запроса, доступного в контексте.
- А «под названием» регистрация решение, основанное не будет масштабируемым, по двум причинам: (всего семейства классов интеграции должен быть включен, и это потребовало бы неуклюжим регистрации имен и условное разрешение в коде, делая его трудно поддерживать).
- Решение должно работать даже тогда, когда имеет место цепочка/иерархия разрешений, то есть прямой потребитель
IIntegrationController
также разрешен через Unity, так как он динамически вводится в другой класс. - Мы опробовали
DependencyOverride
иResolveOverride
класс во время разрешения, но для этого потребуется целый набор разрешений Family-2IIntegrationController
, которые можно переопределить, вместо того, чтобы просто переключаться на весь слой. - Мы понимаем, что вместо того, чтобы вводить контроллер IIntegrationController непосредственно в бизнес-класс, возможно, потребуется ввести AbstractFactory, но мы не сможем добиться этого, и не уверены, где будет происходить регистрация и разрешение. Если бизнес-класс подключен к AbstractFactory, сначала мне нужно будет подключить нужный завод по разрешению,
- Требуется ли это для переопределения
InjectionFactory
? This link предлагает подход, но мы не смогли заставить его работать плавно.
Реальная реализация жизни не совсем ясна для меня. Не могли бы вы добавить ссылку на какой-то код, который использует этот подход? Если у вас есть, конечно. – dmigo