Php 将依赖项注入容器传递给静态方法
我有一些遗留类。 许多类都是使用工厂类实例化的 还有一个单身班 将来我想用DIC完全取代它们。 目前,要做到这一点,代码库太大了 现在,我的目标是将DI容器注入到Singleton类实例化的每个服务中。 Singleton类有一个带有此签名的静态方法Php 将依赖项注入容器传递给静态方法,php,symfony,Php,Symfony,我有一些遗留类。 许多类都是使用工厂类实例化的 还有一个单身班 将来我想用DIC完全取代它们。 目前,要做到这一点,代码库太大了 现在,我的目标是将DI容器注入到Singleton类实例化的每个服务中。 Singleton类有一个带有此签名的静态方法 final class Singleton { private static $singletonCache = array(); public static function getInstance($namespace, $class
final class Singleton
{
private static $singletonCache = array();
public static function getInstance($namespace, $className)
{
}
}
在此函数中,我要检查:
$instance = new $className();
if($instance instanceof ContainerAwareInterface)
{
// TODO: how do we get the container here
$instance->setContainer($container);
}
但是,如何才能最好地将容器放在我的“singleton类”(仅静态调用)中?在引导代码的早期,但在容器实例化之后,您可以将容器传递给singleton类:
Singleton::setContainer($container);
它将容器存储在静态属性中:
final类单例
{
// ...
私人静态容器;
公共静态函数setContainer(ContainerInterface$container)
{
self::$container=$container;
}
}
然而正如您在单例类示例中了解到的,全局状态给您带来的一切都是头痛。传递容器(并使用ContainerWare)是需要避免的。通过将容器传递给您的服务,您使它们依赖于整个服务世界。只传递您实际需要的协作者会更干净。它也更容易测试 另一种方法是在需要时全局访问容器:
public static function getInstance($namespace, $className)
{
$container = $_GLOBAL['kernel']->getContainer();
}
当然,这种方法有很多问题,但只要你正在过渡,就足够了。中给出了另一种解决方案,这与这个问题的另一个答案几乎相同,只需使用
global
关键字而不是$\u global
数组来访问内核对象
public static function getInstance($namespace, $className)
{
global $kernel;
$container = $kernel->getContainer();
}
var_dump($instance)代码>并检查您得到的是什么。这是伪代码。我知道我会得到什么。我的问题是$container在静态方法“getInstance”的上下文中不可用。如何从全局作用域注入它?`$instance->setContainer($container);`在这里,通过传递参数$container
调用方法setContainer
,问问自己,在使用之前从哪里获得它?我知道最佳实践。但是现在我必须保留遗留类,因为有些客户依赖它们。我无法控制代码库,所以我必须保留BC。这有点难以解释,但我将在以后重构并删除整个类。近两年后,我可以说:这一切都很顺利。我添加了带有适当依赖注入的Symfony DiC。然后我编写了一个“facade”容器::get($id)Container::getParam($key)。用它替换了我代码中所有愚蠢的实例化。容器类用于抛出弃用并将其记录到Kibana。后来我删除了这个糟糕的代码:-)很好。谢谢。这很危险,因为它还允许其他人从$\u GLOBAL访问容器。在你试图清理的代码库中,你不应该打开新的机会来搞砸。不管怎样,全球都是存在的。正是Symfony的设计方式。这取决于开发人员是否滥用它。我的问题是有很多狗屎。。。我试着先把东西放到容器中,然后使用服务容器的全局状态。然后我开始反对全局使用,并开始将部件重构为适当的DI。到目前为止,我喜欢这种方法,我几乎已经完成了应用程序的重构。