2

我有一个旧版应用程序,我正在使用 Symfony。到目前为止一切正常。

现在我想为我的 Legacy-Controllers 使用自动装配。

  • 它们是使用作曲家classmap功能加载的
  • 位于根命名空间中(例如\Controller_Page
  • 类名与文件名不同

是的。我知道这很糟糕。但它是遗留问题,我现在不想触及每一个控制器(该应用程序中存在更大的问题)。

我想使用依赖注入和自动装配来减少(可怕的)混乱。

以下是我已经尝试过的一些方法:

services:
 _defaults:
        autowire: true
        autoconfigure: true
    "\\":
        resource: '../legacy/Controller'
        tags: ['controller.service_arguments']

命名空间不是有效的 PSR-4 前缀

services:
 _defaults:
        autowire: true
        autoconfigure: true
    "":
        resource: '../legacy/Controller'
        tags: ['controller.service_arguments']

命名空间前缀必须以“\”结尾

// in Kernel::configureContainer()
$container->registerForAutoconfiguration(\BaseController::class);

(我\BaseController的只有Symfony\Component\HttpFoundation\RequestStackas__construct参数)

控制器“BaseController”具有必需的构造函数参数,并且在容器中不存在。你忘了定义这样的服务吗?

// in Kernel::configureContainer()
$container->registerForAutoconfiguration(\Controller_Legacy::class);

无法加载资源“4208ad7faaf7d383f981bd32e92c4f2f”。

我不知道如何做到这一点。谢谢你的帮助。

编辑 1

又进了一步。我为其中一个传统控制器完成了自动配置,如下所示:

// Kernel.php
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
{
    $container->addDefinitions([
        \Controller_Legacy::class => (new Definition(\Controller_Legacy::class))
            ->setAutowired(true)
            ->setAutoconfigured(true)
            ->addTag('controller.service_arguments'),
    ]);


    // ...
}

所以看来我以前的问题是由 yaml 配置或 smth 引起的,而不是由容器本身引起的。

现在我必须找到一种方法来注册我所有的 Legacy-Controllers。如果我找到一个好的解决方案,我会玩一下并更新。(好的解决方案非常受欢迎)

编辑2

好吧,这不是 YAML 配置。如果我使用 PHP-Configuration 我会遇到同样的问题。

/** @var $this \Symfony\Component\DependencyInjection\Loader\PhpFileLoader */

$definition = new Definition();

$definition
    ->setAutowired(true)
    ->setAutoconfigured(true)
    ->setPublic(false)
;

$this->registerClasses($definition, '\\', '../legacy/*');

命名空间不是有效的 PSR-4 前缀。

我现在将尝试手动注册课程。

4

1 回答 1

0

好的,我在原始问题中添加了导致此结果的步骤。对我来说,这个解决方案有效。它可能不是最好的,但可以解决问题。(尽管开放以获得更好的建议)。

Kernel.php我滥用 composer-Autoloader 来获取我需要的类并将它们注册为服务。由于未使用的服务将被删除,我没有问题:-)

protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
{
    /** @var ClassLoader $classLoader */
    $classLoader = require $this->getProjectDir().'/vendor/autoload.php';

    foreach (array_keys($classLoader->getClassMap()) as $class) {
        $definition = (new Definition($class))
            ->setAutowired(true)
            ->setAutoconfigured(true)
            ->setPublic(false);

        $container->setDefinition($class, $definition);
    }

    // Since my ClassMap contains not only controllers, I add the 'controller.service_arguments'-Tag
    // after the loop.
    $container
        ->registerForAutoconfiguration(\BaseController::class)
        ->addTag('controller.service_arguments');

    // ...
}
于 2019-06-13T22:14:39.430 回答