design-patterns - dependency injection android - Что такое иждивенческая инъекция?

dependency injection unity / design-patterns / language-agnostic / dependency-injection / terminology

Уже было опубликовано несколько вопросов с конкретными вопросами о внедрении зависимостей , например о том, когда его использовать и какие для этого есть фреймворки. Тем не мение,

Peter Mortensen



Answer #1

Без DIP наш код (я назвал этот "класс-потребитель")напрямую связан с конкретной зависимостью,а также часто обременен ответственностью за знание того,как получить экземпляр этой зависимости и управлять им,т.е.концептуально:

"I need to create/use a Foo and invoke method `GetBar()`"
"I need to invoke something which offers `GetBar()`"

Вот простая реализация C#.Ниже приведен класс Consuming:

public class MyLogger
{
   public void LogRecord(string somethingToLog)
   {
      Console.WriteLine("{0:HH:mm:ss} - {1}", DateTime.Now, somethingToLog);
   }
}
public interface IClock
{
    DateTime Now { get; }
}
public class MyLogger : ILogger // Остальное будет зависеть от нашего регистратора.
{
    private readonly TextWriter _output;
    private readonly IClock _clock;

    // Зависимости вводятся через конструктор
    public MyLogger(TextWriter stream, IClock clock)
    {
        _output = stream;
        _clock = clock;
    }

    public void LogRecord(string somethingToLog)
    {
        // Теперь мы можем использовать наши зависимости через абстракцию
        // и без знания продолжительности жизни зависимостей
        _output.Write("{0:yyyy-MM-dd HH:mm:ss} - {1}", _clock.Now, somethingToLog);
    }
}

Может быть построен автоматизированный модульный тест,который окончательно доказывает,что наш регистратор работает правильно,так как теперь у нас есть контроль над зависимостями-временем,и мы можем шпионить за записанным выходом:

[Test]
public void LoggingMustRecordAllInformationAndStampTheTime()
{
    // Договариваться
    var mockClock = new Mock<IClock>();
    mockClock.Setup(c => c.Now).Returns(new DateTime(2015, 4, 11, 12, 31, 45));
    var fakeConsole = new StringWriter();

    // Действовать
    new MyLogger(fakeConsole, mockClock.Object)
        .LogRecord("Foo");

    // Утверждать
    Assert.AreEqual("2015-04-11 12:31:45 - Foo", fakeConsole.ToString());
}

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