DI 中的接口注入章节

Interface Injection chapter in DI

我刚开始学习什么是依赖注入和 InversionOfControll。但我不能得到一件事。接口注入只有当我定义了一些接口,其中描述了需要实现的方法。该方法获取一些 class 的实例作为参数,然后在 class 中实现接口的内容只是描述该方法的主体?

接口只是定义 public 成员 class 应该实现的契约。它不控制实际的实施 - 你需要一个具体的 class 来做到这一点。

// This is only a contract that defines what members
// all concrete types must implement.
public interface ISomeType
{
    void DoSomething();
}

// This class implements the interface. Therefore, it must
// have all of the methods the contract specifies. In some
// languages, this can be done implicitly just by adding the
// member, but it usually must be public.
public class SomeType : ISomeType
{
    public void DoSomething()
    {
        Console.WriteLine("Hello World");
    }
}

当您使 class 实现一个接口时,它隐式意味着 class 的实例可以转换为接口类型。

ISomeType x = new SomeType();

依赖注入利用了这种行为。您通常在映射中同时定义接口类型和具体实现。

container.For<ISomeType>().Use<SomeType>();

然后当服务被声明为将 ISomeType 作为构造函数参数时,映射用于确定创建哪个具体类型的实例。

public class SomeService : ISomeService
{
    private readonly ISomeType someType;

    public SomeService(ISomeType someType)
    {
        if (someType == null) throw new ArgumentNullException("someType");
        this.someType = someType;
    }
}

推荐的方法是允许 DI 容器在组合整个对象图时隐式地执行此操作(在 Composition Root 中),但也可以显式地执行此操作(并且它使更好例子):

ISomeService = container.GetInstance<ISomeService>();

假设容器被配置为将 ISomeService 映射到 SomeService(就像我之前用 ISomeType 展示的那样),这一行代码将创建 SomeService 的实例并自动将 SomeType 的实例注入其构造函数。

不过,很难从一个简单的例子中看出这一点。依赖注入适用于具有多种类型的复杂应用程序。当应用程序复杂时它会简化事情,但当应用程序简单时它有使事情变得更复杂的趋势。