捆绑控制器的依赖注入

时间:2019-05-30 02:11:38

标签: symfony symfony4

我有一个简单的,可以使用的SecurityController,我想将其变成一个捆绑包,以便我可以在自己创建的几个基本网站之间共享基本身份验证功能。一切都按预期进行,直到我尝试将代码打包成一个包为止。

我创建了我的捆绑软件类,一个用来声明我的登录和注销路径的Resources / config / routing.xml文件,在Resources / views / Security / login.html.twig中有一个模板,但是以下类抛出错误

<!-- Controller/SecurityController.php -->
<?php

namespace JustinVoelker\EssentialSecurityBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;

class SecurityController extends AbstractController
{
    private $authenticationUtils;

    public function __construct(AuthenticationUtils $authenticationUtils)
    {
        $this->authenticationUtils = $authenticationUtils;
    }

    public function loginAction()
    {
        $error = $this->authenticationUtils->getLastAuthenticationError();

        return $this->render('@EssentialSecurity/Security/login.html.twig', [
            'error' => $error,
        ]);
    }

    ... Comments and additional functions removed for simplicity

}

我进入登录页面时遇到的错误是Controller "JustinVoelker\EssentialSecurityBundle\Controller\SecurityController" has required constructor arguments and does not exist in the container. Did you forget to define such a service?

在一些不同的示例/教程之后,我尝试创建一个services.xml文件并通过DependencyInjection / EssentialSecurityExtension.php加载它,以尝试使AuthenticationUtils对我的构造函数可用,但似乎没有任何改变。

<!-- DependencyInjection/EssentialSecurityExtension.php -->
<?php

namespace JustinVoelker\EssentialSecurityBundle\DependencyInjection;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;

class EssentialSecurityExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $loader = new XmlFileLoader(
            $container,
            new FileLocator(__DIR__.'/../Resources/config')
        );
        $loader->load('services.xml');
    }
}
<!-- Resources/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>

<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    <services>
        <service id="essential_security.controller"
                 class="JustinVoelker\EssentialSecurityBundle\Controller\SecurityController">
            <argument type="service" id="security.authentication_utils"/>
        </service>
    </services>
</container>

我缺少什么让我可以在将此代码移入捆绑包之前在捆绑包内使用依赖项注入?

如果我只是删除对AuthenticationUtils的任何引用(私有属性,整个构造函数及其在loginAction中的用法),则页面将呈现,尽管没有最后一个我在AuthenticationUtils中使用的身份验证错误,该页面将无法正常运行。第一名。

请注意,如果我将JustinVoelker\EssentialSecurityBundle\Controller\SecurityController: ~手动添加到应用程序的主config / services.xml文件中,那么控制器错误就会消失,以至于我很清楚我的软件包中缺少某些东西,无法正常工作。

也许还有另一种方法可以实现将最后一个身份验证错误消息返回到登录页面的最终目的,但是我的问题是我缺少什么,这阻止了依赖注入在捆绑控制器之前的工作而且在我所见过的许多示例中,它似乎都起作用。

编辑2019-05-30 ,其中包括我的原始routing.xml的一部分

<route id="essential_security_login" path="/login">
    <default key="_controller">EssentialSecurityBundle:Security:login</default>
</route>

1 个答案:

答案 0 :(得分:1)

看起来像在路由中使用JustinVoelker\EssentialSecurityBundle\Controller\SecurityController,但是服务名称为essential_security.controller 您应该更改路由或服务定义

您可以添加别名

<!-- Resources/config/services.xml -->
<service id="JustinVoelker\EssentialSecurityBundle\Controller\SecurityController" alias="essential_security.controller"/>

<service id="essential_security.controller" class="JustinVoelker\EssentialSecurityBundle\Controller\SecurityController">
    <argument type="service" id="security.authentication_utils"/>
    <tag name="controller.service_arguments"/>
</service>

或仅重命名(请注意,您可以省略class参数)

<!-- Resources/config/services.xml -->
<service id="JustinVoelker\EssentialSecurityBundle\Controller\SecurityController">
    <argument type="service" id="security.authentication_utils"/>
    <tag name="controller.service_arguments"/>
</service>

或在您的路由中:

route_name:
    path:     /path
    controller: JustinVoelker\EssentialSecurityBundle\Controller\SecurityController::loginAction
route_name:
    path:     /path
    controller: essential_security.controller::loginAction

取决于您的服务名称