Ответ 1
Вызов конструктора базового класса явным образом является единственным способом сделать это с помощью вставки конструктора в С#. Похоже, вы должны удалить конструкторы без параметров без BaseController
и PublicController
, поскольку их никогда не следует вызывать, когда доступен журнал.
Проблема ввода зависимостей в базовый контроллер является общей с использованием ASP.NET MVC и IoC. Существует несколько вариантов/школ мысли.
1.) Используйте агрегированные услуги. Чтобы упростить конструкторы производных классов, создайте единую службу, которая предоставляет или делегирует все различные службы, необходимые базовому контроллеру (например, IBaseControllerDependencies
или тому подобное.) Затем передайте эту службу в BaseController
так же, как вы делаете с ILogger
здесь.
В зависимости от вашего приложения и количества базовых классов, которые вы используете, есть разные плюсы/минусы. Google для "совокупных сервисов Autofac", чтобы узнать больше об этом.
2.) Используйте инъекцию свойств. Сделайте свойство ILogger
в базовом классе общедоступным и настройте контейнер, используя:
builder.RegisterControllers().PropertiesAutowired();
В Autofac не используется предпочтительный метод вложения свойств. Роль конструктора заключается в том, чтобы принимать зависимости, тогда как записываемые свойства часто воспринимаются как запах кода, поэтому Autofac на самом деле не оптимизирует этот случай. Один из недостатков заключается в том, что записываемые свойства, которые не следует вводить часто, ошибочно, с нечетными последствиями.
3.) Функциональность базового контроллера Refactor в различных фильтрах действий. Autofac может вводить фильтры действий в конвейер вызова действия MVC. Таким образом, фильтры могут принимать зависимости, которые были в базовом классе, и те же проблемы могут быть применены сквозным способом. Подробнее об этом в Интернете, ExtensibleActionInvoker
и .InjectActionInvoker()
укажите информацию, которая вам нужна. Не всегда возможно со всеми проблемами.
4, также ответ на ваш второй вопрос.) Разрешите зависимости базового контроллера, используя местоположение службы из DependencyResolver.Current
.
var logger = DependencyResolver.Current.GetService<ILogger>();
Причина, по которой это не рекомендуется, заключается в том, что она затрудняет понимание получаемого приложения, поскольку уже невозможно увидеть, от каких сервисов зависит компонент, глядя в одном месте (конструктор). Чтобы определить, что должно быть настроено в контейнере, прежде чем какой-либо конкретный компонент может быть использован, нужно найти всю кодовую базу компонента, чтобы найти вызовы GetService()
. Заметное препятствие при тестировании устройства.
Надеюсь, это поможет, кусочек дампа мозга, который я знаю:) Другие, возможно, могут добавить к ним еще несколько идей.