这是一个小代码:
class Mail
{
public $subject;
public function send()
{
DI::get('mailer')->send($this);
}
}
class Mailer
{
public function send(Mail $mail)
{
//
}
}
它的doensnt使用DI,我的意思是Mailer
没有通过构造函数传递给Mail
,只是从容器中取出。但什么时候使用哪个?
答案 0 :(得分:2)
使用IoC容器作为服务定位器is an Anti-Pattern。
您应该更喜欢构造函数注入而不是方法注入或属性注入:
如果没有依赖项,类无法完成其工作,则将其添加到构造函数中。该类需要新的依赖项,因此您希望您的更改能够破坏事物。此外,创建一个未完全初始化的类(“两步构造”)是反模式(IMHO)。如果类可以在没有依赖项的情况下工作,那么setter就可以了。 - Source
对于给定的对象树,只能访问一次IoC容器。当我说accessed
时,我的意思是调用DI::get('X')
。您不应该调用DI::get('X')
对象。您的对象不应该知道IoC容器的存在。
只能从对象图的Composition Root访问IoC容器。
在MVC Web应用程序中,组合根通常是控制器工厂。在控制台应用程序中,可以在main中找到它。