2

Я создаю приложение ASP.NET MVC 5 с использованием шаблонов проектирования репозитория и уровня сервиса. Я использовал единство, чтобы вводить свои услуги в мои контроллеры.Внедрение зависимостей ASP.NET MVC за пределами контроллера с Unity

Это хорошо работает, и до сих пор мне не приходилось учитывать создание экземпляров любых объектов, требующих ввода интерфейсов вне моих контроллеров. Однако мне нужно это при настройке запуска моего приложения для настройки некоторых пользователей в базе данных.

Для этого я хотел использовать мой UsersService, который я создал. И мне пришло в голову, что, когда приложение будет расти, наверняка будут другие случаи, когда я захочу сделать то же самое, например, вызвать службу из другой службы.

Я вижу, что я могу создать экземпляр контейнера Unity и вызвать решимость на него, чтобы получить мой новый экземпляр службы:

IProductService productService = container.Resolve<IProductService>(); 

Однако это своего рода запахи мне, имея контейнер просочилась во всем мое приложение кажется как анти-образец. Так есть лучший способ сделать это?

ответ

4

Unity и другие контейнеры для инъекций зависимостей автоматически делают это. Когда вы вводите службу в контроллер, она автоматически разрешает весь график зависимостей этой службы. Не только может вы решаете зависимости службы и ее зависимостей, то должен устанавливать зависимости в службу, которая им нужна, а не от контроллера.

Любой класс (включая контроллер), который имеет более чем несколько зависимостей, является запахом кода, который вы нарушаете Single Responsibility Principle, и вы, скорее всего, должны refactor to aggregate services.

И да, впрыскивание контейнера в любую точку за пределами composition root составляет an anti-pattern called a service locator.

Что касается инъекционных услуг вне контроллера, важно различать injectables and runtime data. Например, некоторые пытаются внедрить службы в объекты DTO, attributes, статические классы/методы расширения и другие места, где это анти-шаблон для служб, которые будут введены. В этих ситуациях важно правильно оценить ситуацию и реорганизовать ее на решение, благоприятное для DI, - в пользу внедрения конструктора над другими альтернативами и, в качестве последнего средства, использовать локатор сервисов. Например, если вы пытаетесь сделать метод расширения с зависимой службой, скорее всего, у вас есть некоторые функции, которые сам должен быть нестатической службой, DTO никогда не должны создаваться из контейнера DI, и вам, возможно, придется используйте несколько точек расширения в MVC, где вы вводите контейнер в корень композиции приложения, который не является локатором службы.

Стоило ли? Как правило. Что получается? Вы получаете возможность изменять приложение гораздо быстрее, чем если бы у вас было тесно связанное приложение таким образом, что разработчик приложения, возможно, даже не ожидал. Таким образом, дополнительные затраты на обеспечение приложения слабо связаны, как правило, более чем окупаются при постоянном обслуживании проекта. В качестве побочного преимущества вы получаете возможность легко тестировать каждый компонент независимо от других.

+0

Хорошо спасибо за подтверждение существования проблемы с локатором обслуживания. Я вижу, что если я получаю больше, чем около 3-х сервисов, которые вводят свое время для рефакторинга.Что касается всего графика зависимости, который вы упомянули, я полагаю, что это означает, что единство определяет, какие потребности нужно вводить, и какие зависимости этих зависимостей также нужно вводить и так далее. В этом случае, если я вне контроллера, как мне избежать такого: IService1 service1 = new Service1 (новый Service2 (новый Service3())), где service1 зависит от service2, который зависит от service3; –

+0

@PhilipMccarthy - Я обновил свой ответ. – NightOwl888

+0

Большое спасибо, очень полезно. –

Смежные вопросы