Внедрение зависимостей (DI) зависит от интерфейсов? - PullRequest
3 голосов
/ 15 июля 2010

Это может показаться очевидным для большинства людей, но я просто пытаюсь подтвердить, что Dependency Injection (DI) опирается на использование интерфейсов.

Более конкретно, в случае класса, который имеет определенный Интерфейс в качестве параметра в своем конструкторе или определенный Интерфейс, определенный как свойство (иначе, Setter), инфраструктура DI может передать экземпляр конкретного класса удовлетворить потребности этого интерфейса в этом классе. (Приносим извинения, если это описание неясно. У меня возникают проблемы с правильным описанием, потому что терминология / концепции все еще несколько новы для меня.)

Причина, по которой я спрашиваю, состоит в том, что у меня в настоящее время есть класс, который имеет своего рода зависимость. Не столько объектная зависимость, сколько URL. Класс выглядит так [C #]:

using System.Web.Services.Protocols;
public partial class SomeLibraryService : SoapHttpClientProtocol 
{
        public SomeLibraryService() 
        {
            this.Url = "http://MyDomainName.com:8080/library-service/jse";
        }
}

Класс SoapHttpClientProtocol имеет свойство Public с именем Url (которое является простой старой "строкой"), и конструктор здесь инициализирует его жестко закодированным значением.

Могу ли я использовать DI-фреймворк для ввода другого значения при построении? Я думаю, что нет, поскольку this.Url не является чем-то вроде Interface; это String.

[Между прочим, приведенный выше код был «автоматически сгенерирован wsdl», согласно комментариям в коде, с которым я работаю. Так что я не особо хочу менять этот код, хотя я и не вижу, как я его заново генерирую. Так что, возможно, изменение этого кода - это нормально.]

Я мог бы видеть, как я создаю альтернативный конструктор, который принимает строку в качестве параметра и инициализирует this.Url таким образом, но я не уверен, что это правильный подход к сохранению слабосвязанного разделения интересов. (SoC), * * тысяча двадцать-одна

Какой-нибудь совет для этой ситуации?

Ответы [ 4 ]

8 голосов
/ 15 июля 2010

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

Например, класс в библиотеке может вызывать HttpContext.Current внутри, что делает произвольные предположения о приложении, в котором будет размещаться код. DI-версия метода библиотеки будет ожидать, что экземпляр HttpContext будет введен через параметр, и т.д.

5 голосов
/ 15 июля 2010

Нет необходимости использовать интерфейсы - вы можете использовать конкретные типы или абстрактные базовые классы.Но многие преимущества DI (такие как возможность изменения реализации зависимости) появляются при использовании интерфейсов.

Castle Windsor (структура DI, которую я знаю лучше всего), позволяет отображать объекты в IoCконтейнер для интерфейсов или просто имена, которые будут работать в вашем случае.

3 голосов
/ 15 июля 2010

Внедрение зависимостей - это способ организации вашего кода.Возможно, некоторые из ваших заблуждений происходят из-за того, что не существует ни одного официального способа сделать это.Это может быть достигнуто с помощью «обычного» кода на C # или с помощью фреймворка, такого как Castle Windsor.Иногда (часто?) Это предполагает использование интерфейсов.Независимо от того, как это достигается, основной целью DI обычно является сделать ваш код более простым для тестирования и более легким для последующего изменения.

Если бы вы вставили URL в вашем примере через конструктор, этоможно считать «ручным» DI.В статье Википедии о DI есть больше примеров руководства против фреймворка DI.

0 голосов
/ 15 ноября 2013

Я хотел бы ответить с акцентом на использование интерфейсов в приложениях .NET. Полиморфизм в .NET может быть достигнут с помощью виртуальных или абстрактных методов или интерфейсов.

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

«Контракт» функции (или даже свойства) определен, но как метод реализован, логические возможности метода могут отличаться во время выполнения, определяемые тем, какой подкласс создается и передается методу или конструктор, или набор для свойства (акт «инъекции»).

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

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

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

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

Для меня реальная сила IoC-фреймворка - переключать реализацию в тех местах, где вы не можете контролировать создание. Например, в ASP.NET MVC создание класса контроллера выполняется средой ASP.NET, поэтому внедрение чего-либо невозможно. Фреймворк ASP.NET имеет несколько хуков, которые фреймворки IoC могут использовать для «промежуточного» процесса создания и выполнения своей магии.

Люк

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