service - Symfony 4.2 在 vendor/acme/demo-bundle 中创建存储库作为服务
问题描述
我正在处理 vendor/ 目录中的第三方捆绑包。
我有一个看起来像这样的实体类:
/**
* @ORM\Entity(repositoryClass="Acme\DemoBundle\Repository\ArticleRepository")
* @ORM\Table(name="acme_demo_article")
*/
class Article
还有一个像这样的存储库类:
class ArticleRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, Article::class);
}
}
这会产生以下错误:
“Acme\DemoBundle\Repository\ArticleRepository”实体库实现了“Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface”,但找不到它的服务。确保服务存在并标记为“doctrine.repository_service”。
如果我从实体定义中删除 repositoryClass,我不再有错误,我可以从我的控制器中使用学说:
this->getDoctrine()->getRepository(Article::class)->findBy([], null, $limit, ($page - 1) * $limit);
我尝试将存储库作为服务添加到捆绑服务定义中,但它没有改变任何东西:
供应商/Acme/demo-bundle/Resources/config/services.yaml
services:
Acme\DemoBundle\Repository\:
resource: '../../Repository/ArticleRepository.php'
autoconfigure: true
tags: ['doctrine.repository_service']
bin/console debug:autowire 或 debug:container 不会显示该服务。
我还尝试添加扩展名:
namespace Acme\BlogBundle\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
class AcmeBlogExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new YamlFileLoader(
$container,
new FileLocator(__DIR__.'/../Resources/config')
);
$loader->load('services.xml');
}
}
也没有工作。我没有被调用扩展的印象。我尝试向它添加一个构造函数并转储,死在构造函数中,但是没有转储结果。
所以我的问题是如何将我的存储库定义为供应商目录中的服务?
解决方案
经过一番挣扎,我成功地完成了我的任务。我不认为应该这样做,但如果这可以帮助某人......
我在捆绑包的 DependencyInjection 文件夹中添加了:
class AcmeBlogExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new YamlFileLoader(
$container,
new FileLocator(__DIR__.'/../Resources/config')
);
$loader->load('services.yaml');
}
}
我创建了一个编译器(这是我很难弄清楚的部分)来注册我的服务
class RepositoryCompiler implements CompilerPassInterface
{
/**
* @inheritdoc
*/
public function process(ContainerBuilder $container)
{
$container->register('acme_blog.repository', ArticleRepository::class);
}
}
我在我的 Bundle 类中添加了:
class AcmeBlogBundle extends Bundle
{
/** @info this function normally is useless */
public function getContainerExtension()
{
// This is only useful if the naming convention is not used
return new AcmeBlogExtension();
}
/**
* @inheritDoc
*/
public function build(ContainerBuilder $container)
{
$container->addCompilerPass(new RepositoryCompiler());
parent::build($container);
}
}
最后是服务本身:
services:
Acme\BlogBundle\Repository\:
resource: '../../Repository/*Repository.php'
autoconfigure: true
autowire: true
tags: ['doctrine.repository_service']
autoconfigure 和 autowire 没有用,因为当我调试时没有考虑它们:container 看起来像这样:
php bin/console debug:container acme
Information for Service "acme_blog.article.repository"
=======================================================
---------------- -----------------------------------------------
Option Value
---------------- -----------------------------------------------
Service ID acme_blog.article.repository
Class Acme\BlogBundle\Repository\ArticleRepository
Tags doctrine.repository_service
Public yes
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired no
Autoconfigured no
---------------- -----------------------------------------------
一个非常重要的注释让我浪费了很多时间:
每次更改服务后都要清除缓存。即使在开发模式下,它们也不会在每次刷新后重新加载
推荐阅读
- elixir - 与 nil 比较返回 true
- firebase - 如何修复 Xcode 12 beta 6 中的 ASAuthorization 错误?
- angular - 使用@input 对角度组件进行单元测试
- javascript - 循环遍历嵌套的 Typescript 对象
- java - 使用 ObjectOutputStream 将 ArrayList 写入文件时如何保留换行符?
- powershell - PowerShell 在“(”上拆分会引发错误:“没有足够的)”。
- google-apps-script - 用于在从表单插入的行上插入时间戳的 Google 表格脚本
- python - Python 从二进制文件中读取“20”而不是“00”
- foreach - SwiftUI - 在 ForEach 中获取 TextField 数组
- linux - How to send a packed advertising packet with BlueZ 5 and the 5.4 kernel on Ubuntu 20.04