容器 DI 框架

虽然从代码中提取依赖关系以便注入它们会使代码更容易测试,但它会将问题推向层次结构的更高层次,并且还会导致难以构造的对象。已经编写了各种依赖注入框架/ Inversion of Control Containers 来帮助克服这个问题。这些允许注册类型映射。然后,当要求容器构造对象时,这些注册用于解析依赖关系。

考虑这些类:

public interface ILogger {
    void Log(string message);
}

public class ConcreteLogger : ILogger
{
    public ConcreteLogger()
    {
        // ...
    }
    public void Log(string message)
    {
        // ...
    }
}
public class SimpleClass
{
    public SimpleClass()
    {
        // ...
    }
}

public class SomeProcessor
{
    public SomeProcessor(ILogger logger, SimpleClass simpleClass)
    {
        // ...
    }
}

为了构造 SomeProcessor,需要 ILoggerSimpleClass 的实例。像 Unity 这样的容器有助于自动执行此过程。

首先需要构造容器,然后在其中注册映射。这通常只在应用程序中完成一次。发生这种情况的系统区域通常称为组合根

// Register the container
var container = new UnityContainer();

// Register a type mapping.  This allows a `SimpleClass` instance
// to be constructed whenever it is required.
container.RegisterType<SimpleClass, SimpleClass>();

// Register an instance.  This will use this instance of `ConcreteLogger` 
// Whenever an `ILogger` is required.
container.RegisterInstance<ILogger>(new ConcreteLogger());

配置容器后,它可用于创建对象,根据需要自动解析依赖项:

var processor = container.Resolve<SomeProcessor>();