Shopware 6:如何使用自动布线注入实体存储库

Shopware 6: How to inject an entity repository using autowiring

提问人:Benny 提问时间:10/4/2023 最后编辑:Benny 更新时间:10/17/2023 访问量:97

问:

通过 services.xml 向实体存储库注入 Shopware 6 的“经典”方式类似于

# your service/controller
private EntityRepository $productRepository;
...
public function __construct(
   EntityRepository $productRepository
) {
   $this->$productRepository = $productRepository;
}
...
<!-- your services.xml -->
<service id="...">
  <argument type="service" id="product.repository"/>
</service>

现在,如果我想使用 Symfony 的自动布线 - 与上述符号等价的是什么?

(换句话说,我的观点是如何告诉 Symfony 我希望 product.repository 服务是有线的,而不仅仅是通用的 EntityRepository?

Symfony Autowired 购物器皿6

评论

0赞 Bademeister 10/4/2023
仅当服务容器无法扫描类时,才需要创建服务定义。使用自动服务加载时,只需在构造函数中定义类。

答:

2赞 Benny 10/4/2023 #1

我发现的解决方案实际上相当简单明了:-)使用 Autowire 参数属性指定构造函数,如下所示:

    private readonly EntityRepository $productRepository;
    ...
    public function __construct(
        #[Autowire(service: 'product.repository')] EntityRepository $productRepository
    ) {
        $this->productRepository = $productRepository;
    }

如果您遵守 Shopware 的命名约定,您甚至可以省略 Autowire 参数,在上面的示例中,变量名称将被正确解析为服务。(由 @Alex 提供,评论见下文)$productRepository'product.repository'

评论

1赞 Alex 10/11/2023
剧透:这甚至没有必要..Shopware / Symfony从变量名称中知道要注入什么!$productRepository
0赞 Benny 10/12/2023
一个很好的提示,谢谢!我将相应地更新我的回答。
3赞 Matheus Gontijo 10/17/2023 #2

快速解释它是如何在内部工作的,以便您更好地理解。

Shopware首先查找定义,然后在流程中动态创建存储库。CompilerPass

https://github.com/shopware/platform/blob/v6.5.5.1/src/Core/Framework/DependencyInjection/CompilerPass/EntityCompilerPass.php#L35

在容器(属性)中,它最终如下所示:aliasDefinitions

Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $aclRoleRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $aclUserRoleRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appActionButtonRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appActionButtonTranslationRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appCmsBlockRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appCmsBlockTranslationRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appFlowActionRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appFlowActionTranslationRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appFlowEventRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appPaymentMethodRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appScriptConditionRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appScriptConditionTranslationReposito = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appTemplateRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $appTranslationRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $customFieldRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $customFieldSetRelationRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $customFieldSetRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $languageRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $logEntryRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $pluginRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $pluginTranslationRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $scheduledTaskRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $scriptRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $seoUrlRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $seoUrlTemplateRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $versionCommitDataRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $versionCommitRepository = {Symfony\Component\DependencyInjection\Alias} 
Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $versionRepository = {Symfony\Component\DependencyInjection\Alias}

[.....]
[.....]
[.....]
[.....]

所以,换句话说,通常你有这些定义:

MySampleDefinition.php
HelloWorldDefinition.php
MyCustomEntityDefinition.php

您将能够在 PHP 文件上自动访问这样的存储库:


use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;

public function __construct(
    private EntityRepository $mySampleRepository,
    private EntityRepository $helloWorldRepository,
    private EntityRepository $myCustomEntityRepository,
) {
    
}

无需担心手动定义存储库...但是,您必须保持模式的样子,否则您必须显式地传递它EntityRepository $myCustomEntityRepositoryservices.xml