我可以在层次结构中使用DI容器吗?

时间:2015-10-18 06:19:18

标签: oop dependency-injection

我可以在层次结构中使用DI容器来创建新对象吗?对于每个DI容器,您设置依赖项,然后按类型说出getInstance,它会正确创建实例。此外,您可以阅读许多文章,这些文章解释了DI容器应位于main函数的层次结构顶部,并且不应传递或单个传递。但是,如果我想从容器的层次结构中获取容器中的实例呢?

1 个答案:

答案 0 :(得分:1)

避免让应用程序代码(启动代码除外)直接依赖容器或容器上的抽象;这是一种称为Service Locator的反模式。启动代码通常称为Composition Root

组合根是应用程序中单独的。该图层位于其他图层的顶部,例如表示层和业务层。

但这并不意味着在某些条件之后,您无法使用容器以惰性方式创建对象图的一部分。这是一个例子:

// Defined in a shared library of your application, accessible to all other
// code in your application.
public interface ICommandProcessor
{
    public void Process(object command);
}

此接口的可能用法如下:

this.commandProcessor.Process(new ShipOrderCommand(orderId));

虽然抽象没有注意到有关使用可能容器的任何内容,但是这种抽象的实现仍然可以依赖于一个。但由于应用程序代码不应依赖于容器,因此应在Composition Root(应用程序的启动路径)中定义此实现。这允许应用程序不会忘记此类工具的存在,而容器仍可用于解析对象图。以下是一个示例实现:

public class CommandProcessor : ICommandProcessor
{
    private readonly Container container;
    public CommandProcessor(Container container) {
        this.container = container;
    }
    public void Process(object command) {
        Type handlerType = typeof(ICommandHandler<>).MakeGenericType(command.GetType());
        dynamic handler = this.container.GetInstance(handlerType);
        handler.Handle((dynamic)command);
    }
}

很长一段时间,您可以使用容器以延迟方式创建对象图,只要应用程序中使用Container的唯一图层是您的合成根。