1

我有一个项目使用少量 Symfony 组件,包括依赖注入。主要用于小型命令行项目。昨天,我进行了重构以使用依赖注入,现在我正在尝试重构并将 Doctrine 纳入其中。

在添加 DI 之前,我有一个引导文件,用于设置原则并在连接中传递 EntityManager。这不是一个好主意;你可以看到我为什么要重构。

那么,如何建立与 DI 的 Doctrine 连接?起初我以为自动接线会自动处理它。这就是我到目前为止所拥有的。在底部,我将添加一些我尝试过但没有成功但得到不同错误消息的东西。

作曲家.json:

"doctrine/orm": "^2.7",
"symfony/event-dispatcher": "^5.1",
"symfony/dependency-injection": "^5.1",
"symfony/config": "^5.1",
"symfony/yaml": "^5.1",
"symfony/monolog-bundle": "^3.5",
"symfony/process": "^5.1"

安全.yml:

parameters:

services:
  _defaults:
    autowire: true
    autoconfigure: true

  _instanceof:
    Symfony\Component\Console\Command\Command:
      tags: ['command']

  App\:
    lazy: true
    resource: '../src'

  App\Application:
    public: true
    arguments:
      - !tagged command

索引.php:

$container = new ContainerBuilder();

$loader = new YamlFileLoader($container, new FileLocator());
$loader->load(__DIR__ . '/config/services.yml');

//require __DIR__ . '/config/bootstrap.php';

$container->compile();

exit($container->get(Application::class)->run());

当我将 EntityManagerInterface 添加到其中一个命令时,出现错误:

class CreateRecipientCommand extends Command
{
    protected $em;

    public function __construct(EntityManagerInterface $entityManager, string $name = null)
    {
        $this->em = $entityManager;
        parent::__construct($name);
    }
}

错误信息:

 Cannot autowire service "App\Command\CreateRecipientCommand": argument "$entityManager" of method "__construct()" references interface "Doctrine\ORM\EntityManagerInterface" but no such service exists. Did you create a class that implements this interface?

我知道我需要在某个地方引入 Entity Manager 和 Doctrine 工厂,但我不知道怎么做。

在添加 DI 之前,我有一个引导文件,可以像这样设置连接,然后我传递了 $entityManager 变量:

$paths = [dirname(__DIR__) . '/src/Entities'];

$config = Setup::createConfiguration($isDevmode);
$driver = new AnnotationDriver(new AnnotationReader(), $paths);
$connectionParams = [
    'dbname' => 'dbname',
    'user' => 'root',
    'password' => 'root',
    'port' => '3306',
    'host' => 'localhost',
    'driver' => 'pdo_mysql',
];

$config->setMetadataDriverImpl($driver);

$entityManager = EntityManager::create($connectionParams, $config);

我看到有些人在服务中作为工厂建立了联系?但是,我似乎无法再次找到文档。

与工厂合作

我添加了一个返回 EntityManager 连接的 DatabaseFactory。

class DatabaseFactory
{
    public function createManager(ContainerInterface $container)
    {
        $isDevmode = $container->getParameter('doctrine.orm.devmode');

        $paths = [dirname(__DIR__) . '/src/Entities'];

        $config = Setup::createConfiguration($isDevmode);
        $driver = new AnnotationDriver(new AnnotationReader(), $paths);
        
        $connectionParams = [
            'dbname' => $container->getParameter('doctrine.orm.dbname'),
            'user' => $container->getParameter('doctrine.orm.user'),
            'password' => $container->getParameter('doctrine.orm.password'),
            'port' => $container->getParameter('doctrine.orm.port'),
            'host' => $container->getParameter('doctrine.orm.host'),
            'driver' => $container->getParameter('doctrine.orm.driver'),
        ];

        $config->setMetadataDriverImpl($driver);

        return EntityManager::create($connectionParams, $config);
    }
}

services.yaml

Doctrine\ORM\EntityManager:
    factory: ['App\DatabaseFactory', 'createManager']

这现在有效,但我想知道这是否是最好的方法,是否有一个学说工厂我可以调用并传递连接参数?

4

0 回答 0