Абстракции, инъекции твердых тел и свойств по сравнению с инжекцией в конструктор - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть разговор с кем-то на моей работе. Классы и интерфейсы выглядят следующим образом:

public interface ISomeInterface { }

public class ImplementationOfInterface : ISomeInterface { }

public class ClassThatUsesInterface {
    private ISomeInterface _interface;

    public ISomeInterface Interface {
         get => _interface ?? new ImplementationOfInterface();
         set => _interface = value;
    }
}

99% времени мы будем использовать ImplementationOfInterface. Последние 1%, вероятно, будут использоваться для модульного тестирования.

Я попытался прочитать о внедрении зависимостей, принципе инверсии зависимостей, сервисе, SOLID и о некоторых других вещах, таких как шаблон / анти-шаблон сервисного локатора, двухэтапный анти-шаблон инициализации и т. Д., Но не нашел никого, кто бы описывал этот способ сделать это.

На полпути ясно, что D в SOLID нарушается; «Принцип инверсии зависимостей; нужно «зависеть от абстракций, а не от конкреций». Поскольку это довольно легко переопределить в модульных тестах или переключить реализацию, если вы хотите ... что еще больше запутывает меня в этом ..

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

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

Можете ли вы придумать статьи или весомые аргументы за и против использования этого конкретного "хака"?

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Тот факт, что ClassThatUsesInterface даже нужно знать , что ImplementationOfInterface существует, является запахом кода. Вам может понадобиться добавить директиву using для какого-то совершенно не связанного пространства имен, чтобы скомпилировать его, возможно, даже ссылку на какой-то другой проект или пакет или dll. Итак, ваш код начинает запутываться, и ваши зависимости начинают вызывать головные боли.

Я понимаю, что это урезанный демонстрационный пример, но ImplementationOfInterface просто происходит , чтобы не принимать никаких зависимостей. Что делать, если это сделал? Не могли бы вы по очереди? И их зависимости ..? Затем это показывает, что вы нарушаете другой принцип SOLID - вам нужно будет изменять этот класс каждый раз, когда вы изменяете аргументы ctor на ImplementationOfInterface. Это нарушает принцип открытия / закрытия.

0 голосов
/ 07 ноября 2018

Используйте конструктор для внедрения зависимости. Вы не хотите разрешать изменение реализации на полпути во время жизни экземпляра ClassThatUsesInterface

Обратите внимание, что некоторые платформы или реализации DI не поддерживают внедрение свойств. Например, Asp.Net Core.

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

...