DI, насколько я понимаю, предлагает возможность уменьшить зависимости, позволяя вводить зависимость (обычно через контейнер) через ctor, свойство или метод.
Неправильно.Статический анализ кода показывает, что зависимость все еще существует.Я просто изменяю то, как вы получили экземпляр объекта.Если ваша ctor
говорит, что ожидает объекты определенного класса, то у вас есть зависимость от этого типа, но у вас также есть сильная связь с классом, который плохой .Однако, если ваш ctor
ожидает типы определенного interface
, то у вас есть зависимость от этого определения контракта, но не от фактической реализации ( потеря связи ).
Насколько я понимаю, интерфейсы в C # могут рассматриваться как контракт или обещание, которому должен следовать производный класс.Это позволяет различным объектам вести себя по-разному, когда вызывается переопределенный метод.
Да, но они также являются способом абстрагировать компонент, скрывая ненужные детали, что-то, что класс не может.Вот почему в достаточно больших системах хорошо иметь MyContracts.dll, в котором вы определяете все свои interface
s;и скажем BusinessLogic.dll и ClientStuff.dll.ClientStuff зависит от контрактов, но не заботится о фактической реализации и возможных миллионах других зависимостей, которые может иметь BusinessLogic.dll (скажем, типичное приложение WPF или WCF).
Когда более важно использоватьинтерфейсы для полиморфизма или DI, когда вы хотите полную свободу?Где вы проводите черту?Можно ли использовать интерфейсы, когда вы хотите, чтобы структура (методы и свойства) выравнивались между различными производными классами и DI, когда параметры могут сильно отличаться?
DI не предлагает больше свободы, чем aсистема без DI.Однако я думаю, что вы можете быть немного смущены терминологией или понятиями.Я всегда хорош.Внедрение интерфейсов через типы классов лучше, как я уже упоминал выше.
Я могу создать контракт, в котором говорится, что производный класс ДОЛЖЕН следовать этим определенным правилам, который по своей природе является ограничительным по сравнению с DI, что позволяет вводить зависимости
Контракт - это контракт, который является контрактом в форме интерфейса или абстрактного класса.Если конструктор (внедрение-конструктор) или свойство (внедрение-свойство) запрашивает MyDbConnection
, то это устанавливает требование относительно того, что может быть введено , тем более , чем просто ожидание IMyDbConnection
.
Я думаю, что вы можете ошибаться в отношении того, что делает DI.DI не всегда внедряет классы и интерфейсы не только для полиморфизма.Последнее является распространенной ошибкой.DI не имеет никакого отношения к тому, чтобы быть "ограничительным" .От вас зависит, какой тип вы ожидаете внедрить.
Фактически ожидание, что конкретный объект класса или что-то, производное от абстрактного класса, будет внедрено, будет более «ограничительным» , чемВнедрение интерфейса по самой природе того, как интерфейсы могут быть повторно использованы в других сценариях.Например, не то, чтобы вы вводили один, но INotifyPropertyChanged
с предварительным кодом WPF, но не играли огромную роль в WPF и MVVM.
Ограничительный:
public EditPatientViewModel (SqlPersistenceService svc) {}
Не такой ограничительный
public EditPatientViewModel (IPersistenceService svc) {}
Выбор между ограничением и свободой (Интерфейсы и внедрение зависимостей)
Это зависит только от вас, но если вы добавите интерфейсы, то получите:
- разделение между контрактом и реализацией и всем багажом, который идет с ним
- улучшенная абстракция - спрячьте ненужные детали