我有一个项目使用少量 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']
这现在有效,但我想知道这是否是最好的方法,是否有一个学说工厂我可以调用并传递连接参数?