Ограничивает ли шаблон DI создание дорогостоящих объектов в сочетании с нечастым использованием зависимостей? - PullRequest
8 голосов
/ 05 августа 2011

Мне трудно разобраться с тем, что кажется очевидной проблемой / ограничением шаблона, когда дело доходит до типичного внедрения зависимостей в конструктор. Например, допустим, у меня есть контроллер ASP.NET MVC3, который выглядит следующим образом:

Public Class MyController
    Inherits Controller

    Private ReadOnly mServiceA As IServiceA
    Private ReadOnly mServiceB As IServiceB
    Private ReadOnly mServiceC As IServiceC

    Public Sub New(serviceA As IServiceA, serviceB As IServiceB, serviceC As IServiceC)
        Me.mServiceA = serviceA
        Me.mServiceB = serviceB
        Me.mServiceC = serviceC
    End Sub

    Public Function ActionA() As ActionResult
        ' Do something with Me.mServiceA and Me.mServiceB
    End Function

    Public Function ActionB() As ActionResult
        ' Do something with Me.mServiceB and Me.mServiceC
    End Function
End Class

Мне трудно преодолеть тот факт, что контейнеру DI было предложено создать все три зависимости , когда в любой момент времени может потребоваться только подмножество зависимостей. методы действия на этом контроллере.

Кажется, предполагается, что конструкция объекта является грязной и нет побочных эффектов от конструкции объекта ИЛИ все зависимости последовательно используются . Что, если конструкция объекта не была дешевой или были побочные эффекты? Например, если построение IServiceA связано с открытием соединения или выделением других значительных ресурсов, то при вызове ActionB это будет напрасно потрачено время / ресурсы.

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

Использует ли канонический шаблон инъекция конструкторов + интерфейсы шаблона DI, в основном, замкнул разработчика на «ограничение» того, что реализации зависимости должны быть дешевыми, чтобы реализовать их, или экземпляр должен быть значительно использован? Я знаю, что у всех моделей есть свои плюсы и минусы, это только один из минусов ДИ? Я никогда не видел, чтобы это упоминалось ранее, что мне кажется любопытным.

Ответы [ 4 ]

6 голосов
/ 08 августа 2011

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

Если это так, то рефакторинг (например, Facade Services ).

Вам не нужно беспокоиться о производительности при создании графов объектов .

Когда речь идет о побочных эффектах, конструкторы (DI) должны быть простыми и не иметь побочных эффектов..

5 голосов
/ 05 августа 2011

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

Относительно экземпляров, которые остаются неиспользованными: сложно создать систему, которая будет идеально использовать экземпляры в зависимых классах, независимо от того, используете ли вы DI или нет. Я не уверен, что достижение этого очень важно, если вы придерживаетесь Принципа единой ответственности . Если вы обнаружите, что в ваш класс введено слишком много служб или использование действительно неравномерно, это может быть признаком того, что ваш класс делает слишком много и его нужно разделить на два или более меньших класса с большим сфокусированные обязанности.

2 голосов
/ 05 августа 2011

Нет, вы не привязаны к перечисленным ограничениям.Начиная с .net 4 у вас есть Lazy (Of T) , что позволит вам отложить создание экземпляров ваших зависимостей до тех пор, пока они не потребуются.

Не предполагается, что строительство объекта дешевое и, следовательно, некоторые контейнеры DI поддерживают Lazy(Of T) из коробки.В то время как Unity 2.0 поддерживает ленивую инициализацию из коробки через автоматические фабрики , есть хорошая статья здесь о расширении, поддерживающем Lazy(Of T), автор имеет на MSDN .

0 голосов
/ 05 августа 2011

Хотя ваш контроллер не синглтон? Это нормальный способ сделать это в Java. Создан только один экземпляр. Также вы можете разделить контроллер на несколько контроллеров, если роли действий настолько различны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...