IoC.Resolve по сравнению с инжекцией конструктора

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

теперь преимущества использования Твердости вместо Инжекции Конструктора состоят в том, что Вы не должны создавать классы, которые имеют 5 параметров в конструкторе, и каждый раз, когда Вы собираетесь создать экземпляр того класса, Вы не собираетесь, должен предоставить ему что-либо

44
задан alexandrul 19 May 2010 в 09:09
поделиться

7 ответов

IoC.Resolve <> - это пример шаблона Service Locator . Этот шаблон накладывает несколько ограничений, которых нет при внедрении конструктора:

  • Объекты не могут иметь более детального контекста, чем домен приложения, из-за статических вызовов
  • Объекты решают , какие версии зависимостей использовать разрешить.Все экземпляры определенного класса получат одинаковую конфигурацию зависимости.
  • Велик соблазн связать код с контейнером, например, вместо создания фабрики выявления намерений.
  • Модульное тестирование требует конфигурации контейнера, в котором классы можно было бы просто создать и использовать в противном случае. (Это особенно неприятно, когда вы хотите протестировать несколько конфигураций одного и того же класса из-за второй проблемы, описанной выше.)
  • Структура приложения не может быть выведена из его общедоступного API. (Параметры конструктора - это хорошая вещь. Это не проблема, которую вы должны решить.)

Эти ограничения, на мой взгляд, ставят шаблон Service Locator на середину между большими и ... комок грязи и инъекция зависимостей: полезно, если вы должны его использовать, но, безусловно, не лучший выбор.

49
ответ дан 26 November 2019 в 22:02
поделиться

Если вы создаете классы, которые имеют 5 зависимостей, у вас есть проблемы, отличные от IOC.RESOLVE.

Вытягивание зависимостей (в отличие от того, что они нажали через конструктор), полностью пропускают точку использования IOC Framework. Вы хотите инвертировать зависимости. Нет ваших классов зависят от структуры МОК, но наоборот.

Если вам не нужны все зависимости в некоторых сценариях, чем, возможно, вы должны разделить свой класс или иметь некоторые зависимости, сделанные необязательно, сделав их зависимости свойства.


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

26
ответ дан 26 November 2019 в 22:02
поделиться

Одним из преимуществ является то, что с инъекцией конструктора все классовые зависимости видны вверх-фронта.

С . Aresolve Вы должны прочитать код, чтобы понять зависимости.

3
ответ дан 26 November 2019 в 22:02
поделиться

Невозможно заставить pg_dump Давить данные в каком-либо конкретном порядке, так как он сбрасывает данные в заказе на диск - это намного быстрее таким образом.

Вы можете использовать параметры «-D -D» для PG_Dump, а затем «сортировать» вывод, но в Newlines в данных сделает отсортированные выходные данные непригодными для использования. Но для базового сравнения, изменилось ли что-то, это хватило бы.

-121--2308850-

Я должен указать, что это не обязательно зло, чтобы пропустить инъекцию конструктора и использовать статическую инъекцию. Существуют отличные приложения этого, наиболее конкретным примером используют его в реализации заводской структуры.

public static class ValidationFactory
{
    public static Result Validate<T>(T obj)
    {
        try
        {
            var validator = ObjectFactory.GetInstance<IValidator<T>>();
            return validator.Validate(obj);
        }
        catch (Exception ex)
        {
            var result = ex.ToResult();
            ...
            return result;
        }
    }    
}

Я использую это со структурой для обработки моего уровня проверки.

Отредактируйте: Другим примером У меня напрямую использование контейнера - сделать некоторые из ваших доменных объектов BE Singletons, не делая их статическими классами и внедряя всю стратую страту, которые делают статические классы.

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

SomeObject ISomeView.GetMyObject
{
    get { return new SomeObject { EmpoweredEnumType = 
            ObjectFactory.GetNamedInstance<IEmpEnum>("TheObjectName");
        }
}
1
ответ дан 26 November 2019 в 22:02
поделиться

Вам не нужно создавать классы, имеющие 5 параметров в конструкторе, и всякий раз, когда вы собираетесь создать экземпляр этого класса, вам не нужно будет предоставлять ему все

Пара очков:

  • Если вы используете DI-контейнер, он должен создавать экземпляры этого класса для вас. В этом случае вам не нужно предоставлять ему что-либо сами для производства. Для тестирования вам придется предоставить ему зависимости через конструктор, но:
  • , если класс зависит от (использует каким-то образом) те 5 вещей, которые вы говорите о предоставлении конструктору (и вы бы Т не предоставляя им, если он не должен) вам придется предоставлять им так или иначе. При тестировании (который является единственным раз, когда вам нужно позвонить в конструктор самостоятельно), вы можете либо передавать эти вещи через конструктор, или вы можете написать код, чтобы настроить контейнер и добавить эти 5 вещей, чтобы, когда IOC.RESOLVE () вызывается, они на самом деле там. Сдача их до конструктора намного проще, я бы сказал.

Зависимости будут существовать, даже если вы не сделаете это очевидным через API класса (это конструктор в этом случае). Тем не менее, это будет намного сложнее понимать и тестировать классы, которые пытаются скрыть такие зависимости.

0
ответ дан 26 November 2019 в 22:02
поделиться

Ioc.Resolve - это, по сути, шаблон Service Locator. Он имеет свое место, но не идеален. Внедрение конструктора предпочтительнее с точки зрения архитектуры, поскольку зависимости более явны, тогда как SL скрывает зависимости внутри класса. Это снижает возможность тестирования и делает процесс более сложным, чем он должен быть.

Если позволите, я бы посоветовал вам прочитать мою серию о методах уменьшения кодовой связанности, которая охватывает SL, DI и IoC.

7
ответ дан 26 November 2019 в 22:02
поделиться

Я бы сказал, что нужно ввести безумное количество параметров.

Стремитесь к одному параметру, может быть, максимум 2, что есть почти во всех сценариях, и, конечно же, должно быть интерфейсом. Более того, я чувствую запах крысы (недостаток дизайна).

0
ответ дан 26 November 2019 в 22:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: