У меня есть следующая архитектура, в которой общедоступный класс Service, ссылающийся на внутренний класс Helper, существует в другой сборке:
ApplicationAssembly {
public class Widget {
public Widget(ReferencedAssembly.Service service) { ... }
}
}
ReferencedAssembly {
public class Service {
public Service(Helper helper) { ... }
}
class Helper { ... }
}
(Я понимаю, что не могу поместить внутренний класс в аргументы конструктора открытого класса - я просто пытаюсь проиллюстрировать шаблон IoC, который я собираюсь выполнить.)
Проблема в том, что ApplicationAssembly
не может видеть ReferencedAssembly.Helper
, поэтому он не может быть зарегистрирован в моем контейнере IoC (в данном случае Autofac). В результате невозможно разрешить Helper
, когда я пытаюсь разрешить Service
. Какой мой лучший вариант здесь?
Вариант 1: Удалить Helper
из конструктора Service
и явно добавить его в конструктор. Мне не нравится этот вариант, потому что он как бы нарушает парадигму IoC.
Вариант 2: заставить Helper
реализовать общедоступный интерфейс IHelper
, затем добавить публичный модуль в ReferencedAssembly
, который регистрирует Helper
как IHelper
. Мне не нравится эта опция, потому что она требует ApplicationAssembly
, чтобы знать слишком много деталей реализации о Service
, и если пользователь забывает зарегистрировать этот модуль при запуске, все ломается.
Вариант 3: Создайте открытый статический конструктор на Service
, который создает второй контейнер IoC специально для ReferencedAssembly
и регистрирует в нем Helper
. Удалите Helper
из конструктора Service
и разрешите его в конструкторе, используя второй контейнер IoC. Это похоже на мой лучший вариант, но требует большего количества «слесарного» кода, чем другие. Я также не большой поклонник публичных статических конструкторов.
Вариант 4. Измените мою архитектуру на что-то совсем другое.