.NET FrameworkВнедрение зависимости


замечания

Проблемы, решаемые путем инъекций зависимостей

Если бы мы не использовали инъекцию зависимостей, класс Greeter мог бы выглядеть примерно так:

public class ControlFreakGreeter
{
    public void Greet()
    {
        var greetingProvider = new SqlGreetingProvider(
            ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString);
        var greeting = greetingProvider.GetGreeting();
        Console.WriteLine(greeting);
    }
}

Это «контрольный урод», потому что он контролирует создание класса, предоставляющего приветствие, он контролирует, откуда приходит строка подключения SQL, и он контролирует вывод.

Используя инъекцию зависимостей, класс Greeter отказывается от этих обязанностей в пользу единой ответственности, написав приветствие, предоставленное ему.

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

Инъекционная инъекция помогает нам достичь этой инверсии зависимостей, поскольку она приводит к написанию классов, которые зависят от абстракций. Класс Greeter «ничего не знает» о деталях реализации IGreetingProvider и IGreetingWriter . Он знает только, что введенные зависимости реализуют эти интерфейсы. Это означает, что изменения в конкретных классах, которые реализуют IGreetingProvider и IGreetingWriter , не будут влиять на Greeter . Они не заменят их совершенно разными реализациями. Только изменения в интерфейсах будут. Greeter развязан.

ControlFreakGreeter невозможно правильно протестировать. Мы хотим протестировать одну небольшую единицу кода, но вместо этого наш тест будет включать подключение к SQL и выполнение хранимой процедуры. Это также будет включать тестирование вывода консоли. Поскольку ControlFreakGreeter делает так много, невозможно проверить изолированно от других классов.

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

Конкретные реализации IGreetingProvider и IGreetingWriter могут стать более сложными. У них, в свою очередь, могут быть свои собственные зависимости, которые вводятся в них. (Например, мы бы SqlGreetingProvider строку подключения SQL в SqlGreetingProvider .) Но эта сложность «скрыта» от других классов, которые зависят только от интерфейсов. Это облегчает изменение одного класса без «эффекта пульсации», который требует от нас внести соответствующие изменения в другие классы.

Внедрение зависимости Связанные примеры