Глобальный доступ к преобразователю зависимостей autofac в ASP.NET MVC3?
Я использую Autofac с интеграцией ASP.NET MVC, все мои контроллеры получают зависимости, и Autofac автоматически разрешает вложенные зависимости. Отлично работает
Но как я могу разрешить зависимость вне области экземпляра контроллера? В некоторых местах, глубоко в моем коде, мне нужно спросить у моего регистратора. С одной стороны, кажется неправильным передавать Logger в зависимость от каждого маленького объекта, который я создаю, а с другой стороны, кажется неправильным зависеть от зависимого преобразователя настолько глубоко в моем коде
Например, у меня есть класс под названием Result, который возвращается из многих действий. Это постоянный используемый объект, который мой код приложения может опираться на возвращение с более глубоких слоев. Когда более глубокий слоистый код добавляет ошибку пользовательского интерфейса к этому объекту, я хочу автоматически добавить его в регистратор, который требует разрешения. Если каждый класс будет зависеть от регистратора, он просто встанет на пути
Любая благодарная благодарность
Ответы
Ответ 1
Ну, вы можете использовать eventing (pub/sub approach), если зависимость в каждом объекте раздражает вас, но я не уверен, что что-то не так с зависимостью от центрального регистратора Logger.
Если вам действительно нужно регистрироваться из каждого класса, вы можете приблизиться к регистрации как к самому основному аспекту вашего приложения, и вы мысленно рассмотрите его как другие общие типы библиотек, такие как String или Ints, которые являются повсеместными и безопасными в зависимости от.
Но я бы предложил вам что-то еще. ИМХО, вы должны заново создавать архитектуру и не регистрироваться в каждом классе. Если ваше ведение журнала является только (или в основном) о написании ошибок (исключений), то не используйте для этого свою модель домена. Поместите его в Service layer insteád. Этот тип оркестрового слоя может правильно оценивать каждое обнаруженное исключение и записывать только то, что необходимо. Пусть пузырьки эти исключения на более низкий возможный palce в трассировке стека и обрабатывать их как последнюю вещь.
Ответ 2
То, что вы ищете, это MVC DependencyResolver.Current
:
var logger = DependencyResolver.Current.GetService<ILogger>();
Ответ 3
Использование DependencyResolver.Current - это определенно способ решения вашей проблемы в ASP.NET MVC, учитывая, что это функция структуры. Однако сначала я попытался бы выполнить следующую рекомендацию в разделе "Best Practices" раздела Autofac Wiki
"Предоставление доступа к компонентам в контейнере, хранение его в общедоступном статическом свойстве или выполнение функций, таких как Resolve(), доступных в глобальном классе" IoC ", поражает цель использования инъекции зависимостей. Такие проекты имеют больше общего с Шаблон локатора обслуживания.
Если компоненты имеют зависимость от контейнера, посмотрите, как они используют контейнер для извлечения служб, и вместо этого добавьте эти службы к аргументам конструктора, зависящим от компонента (зависимости).
Используйте типы отношений для компонентов, которые должны создавать экземпляры других компонентов или взаимодействовать с контейнером более продвинутыми способами.
Только если невозможно переформулировать зависимость, как было предложено выше, я бы использовал DependencyResolver.
Ответ 4
Люди, которые ищут другое решение этой проблемы, могут посмотреть на этот другой SO ответ, который использует IComponentContext
службу распознавателя, введенную непосредственно Autofac.