DI或DI/服务定位器容器


DI or DI/Service Locator container?

下面是一小段代码:

class Mail
{
    public $subject;
    public function send()
    {
        DI::get('mailer')->send($this);
    }
}
class Mailer
{
    public function send(Mail $mail)
    {
        //
    }
}

它不使用DI,我的意思是Mailer不是通过构造函数传递给Mail,只是从容器中取出。但是什么时候用哪个呢?

使用IoC容器作为服务定位器是一种反模式。

比起方法注入或属性注入,你应该更喜欢构造函数注入:

如果类没有依赖项就不能完成工作,那么将它添加到构造函数中。类需要新的依赖项,所以您希望您的更改会破坏一些东西。另外,创建一个没有完全初始化的类("两步构造")是一种反模式(IMHO)。如果类可以在没有依赖的情况下工作,那么setter就可以了。——源

对于给定的对象树,您的IoC容器应该只被访问一次。当我说accessed时,我指的是调用DI::get('X')。对象不应该调用DI::get('X')。你的对象不应该知道IoC容器的存在。

IoC容器只能从对象图的Composition根目录访问。

在MVC web应用程序中,复合根通常是一个控制器工厂。在控制台应用程序中可以在main.
中找到它。