有两种模式通常用于IoC,并且两者的支持者.
>依赖注入
>服务定位器
然而,越来越多的DI似乎赢得了服务定位器模式.许多DI容器使得使用服务定位器变得更加困难,并且在文档中警告不会下降.
在DI中,除非该类是composition root的一部分,否则您不会将容器传递给类.组合根通过在应用程序的入口点处解析对象图来启动所有动作,并且应用程序从该应用程序完全不知道DI容器(没有参考).请注意,此对象图可能包含创建类的运行时实例的Abstract Factories(通过注入从DI容器中解析的功能或通过将其更新).
服务定位器是频谱的另一端.通常,容器是静态的,或者作为唯一的依赖关系传递给一个类.以这种方式构建课程可能会更容易,但是在您实际需要配置DI容器时,您会付出代价.
使用DI,类的依赖关系是显式的,因此您不需要再看看构造函数的参数.使用服务定位器,配置依赖关系要复杂得多.这是主要原因(实际上有很多原因)为什么近年来被认为是anti-pattern.
所以,为了回答你的问题,如果你想遵循IoC的现代化方法,不要将IoC容器传递到应用程序中.相反,在应用程序的入口点使用组合根配置容器并构建对象图.
依赖注入示例
所以,给你的例子:
class Dog
{
public function woof($var1, $var2)
{
//$request = IoC service here
}
}
你需要添加一个构造函数来接受你的$request服务,所以你的类将会收到一个实例.
class Dog
{
protected $request;
public function __construct(Request $request)
{
$this->request = $request;
}
public function woof($var1, $var2)
{
//Use $request here, disregard the IoC container
$this->request->doSomething()
}
}
然后,您将有一个部分,您可以在组态根目录中定义控制器.这是依赖关系的注入.
$container = new Injection\Container();
$container['config'] = function ($c) {
return new Config($c['loader']);
};
$container['request'] = function ($c) {
return new Request($c['config']);
};
$container['dog'] = $container->factory(function ($c) {
return new Dog($c['request']);
});
$container['user_controller'] = $container->share(function ($container) {
return new UserController(
$container['dog'] //,
// $container['someOtherDependency']
);
});
您可以看到,使用这种方法,您的Dog类完全不知道DI容器.