如果我没有/无法使用 DI 注入服务,如何直接从容器获取服务?

Krz*_*ski 5 php dependency-injection service-locator symfony symfony4

我有一部分代码,通过依赖注入注入两个$checker服务$paginator。它工作完美:

public function index(Request $request, Paginator $paginator, Checker $checker)
    {
        $result = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
        $partialResult = $paginator->getPartial($result, 0, 3);
        $checker->isValid('A');
        var_dump("test");
        die;
    }
Run Code Online (Sandbox Code Playgroud)

文件配置如下services.yaml

   paginator:
        public: true
        class: 'App\Helper\Paginator'

    checker:
        public: true
        class: 'App\Helper\Checker'
        arguments:
         $paginator: '@paginator'
Run Code Online (Sandbox Code Playgroud)

但由于某些原因我想通过方法注入服务:

$checker = $this->container->get('checker');
Run Code Online (Sandbox Code Playgroud)

但这不起作用。在以前的版本中,Symfony 就像 3.4 一样。

我收到错误:

找不到服务“检查器”:事件虽然存在于应用程序的容器中,但“App\Controller\DefaultController”内的容器是一个较小的服务定位器,只知道“http_kernel”、“parameter_bag”、“request_stack”、“router” ”、“会话”和“树枝”服务。尝试使用依赖注入来代替。

我应该如何解决这个问题?

yiv*_*ivi 9

您需要添加依赖项,以便服务定位器可以找到它们

添加一个方法getSubscribedServices()到你的控制器类:

public static function getSubscribedServices()
{
    return array_merge(
        parent::getSubscribedServices(),
        [
            'checker' => Checker::class,
        ]
    );
}
Run Code Online (Sandbox Code Playgroud)

如果您的控制器类扩展,AbstractController您可以简单地执行以下操作:

$this->get('checker');
Run Code Online (Sandbox Code Playgroud)

如果您想在另一种类型的类中执行此操作(例如,不扩展的服务AbstractController),那么您需要声明您的服务实现了ServiceSubscriberInterface.

public static function getSubscribedServices()
{
    return array_merge(
        parent::getSubscribedServices(),
        [
            'checker' => Checker::class,
        ]
    );
}
Run Code Online (Sandbox Code Playgroud)

...您将能够比之前在控制器中执行相同的操作。