我正在学习Symfony,我一直在尝试使用存储库创建服务。 我已经从generate:entity创建了我的存储库和实体,所以它们应该没问题。
到目前为止,我在services.yml中得到的是:
parameters:
mytest.entity: TestTestBundle:Brand
mytest.class: Test\TestBundle\Entity\Brand
default_repository.class: Doctrine\ORM\EntityRepository
services:
myservice:
class: %default_repository.class%
factory-service: doctrine.orm.default_entity_manager
factory-method: getRepository
arguments:
- %mytest.entity%
但是当我尝试调用该服务时,我收到此错误:
Catchable Fatal Error: Argument 2 passed to Doctrine\ORM\EntityRepository::__construct() must be an instance of Doctrine\ORM\Mapping\ClassMetadata, none given, called in
然后我尝试使用实体创建服务。我的services.yml看起来像:
services:
myservice:
class: %mytest.class%
factory-service: doctrine.orm.default_entity_manager
factory-method: getRepository
arguments:
- %mytest.entity%
但为此,我得到:
Error: Call to undefined method
Test\TestBundle\Entity\Brand::findAll
有人知道我做错了什么吗?
由于
答案 0 :(得分:42)
弃权警告:不再有factory_service
和factory_method
。这是你应该如何做到的,因为 Symfony 2.6 (对于 Symfony 3.3 + 检查下面):
parameters:
entity.my_entity: "AppBundle:MyEntity"
services:
my_entity_repository:
class: AppBundle\Repository\MyEntityRepository
factory: ["@doctrine", getRepository]
arguments:
- %entity.my_entity%
新的setFactory()方法是在Symfony 2.6中引入的。有关2.6之前的工厂的语法,请参阅旧版本。
http://symfony.com/doc/2.7/service_container/factories.html
编辑:看起来他们一直在改变这一点,所以自 Symfony 3.3 以来,我们有了新的语法:
# app/config/services.yml
services:
# ...
AppBundle\Email\NewsletterManager:
# call the static method
factory: ['AppBundle\Email\NewsletterManagerStaticFactory', createNewsletterManager]
检查出来:http://symfony.com/doc/3.3/service_container/factories.html
答案 1 :(得分:24)
以下是我们在KnpRadBundle中的表现:https://github.com/KnpLabs/KnpRadBundle/blob/develop/DependencyInjection/Definition/DoctrineRepositoryFactory.php#L9
最后它应该是:
my_service:
class: Doctrine\Common\Persistence\ObjectRepository
factory_service: doctrine # this is an instance of Registry
factory_method: getRepository
arguments: [ %mytest.entity% ]
<强>更新强>
从2.4开始,doctrine允许覆盖默认的repositor工厂。
以下是在symfony中实现它的可能方法:https://gist.github.com/docteurklein/9778800
答案 2 :(得分:10)
您可能使用了错误的YAML-Keys。你的第一个配置对我来说很好用
答案 3 :(得分:2)
自2017年起,Symfony 3.3 + 现在变得更加容易了。
注意:尽量避免像generate:entity
这样的通用命令。他们被设计为能够快速完成项目工作的初学者。他们倾向于暴露不良行为并花费很长时间来改变。
查看我的帖子How to use Repository with Doctrine as Service in Symfony 以获得更详细的说明。
致你的代码:
# app/config/services.yml
services:
_defaults:
autowire: true
Test\TestBundle\:
resource: ../../src/Test/TestBundle
<?php
namespace Test\TestBundle\Repository;
use Doctrine\ORM\EntityManagerInterface;
class BrandRepository
{
private $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(Brand::class);
}
public function findAll()
{
return $this->repository->findAll();
}
}
use Test\TestBundle\Repository\BrandRepository;
class MyController
{
/**
* @var BrandRepository
*/
private $brandRepository;
public function __construct(BrandRepository $brandRepository)
{
$this->brandRepository = $brandRepository;
}
public function someAction()
{
$allBrands = $this->brandRepository->findAll();
// ...
}
}
答案 4 :(得分:0)
我将service.yml转换为service.xml,并更新DependencyInjection Extension,一切都适合我。我不知道为什么,但yml配置会抛出Catchable Fatal Error。您可以尝试使用xml config进行服务配置。
service.yml:
services:
acme.demo.apikey_userprovider:
class: Acme\DemoBundle\Entity\UserinfoRepository
factory-service: doctrine.orm.entity_manager
factory-method: getRepository
arguments: [ AcmeDemoBundle:Userinfo ]
acme.demo.apikey_authenticator:
class: Acme\DemoBundle\Security\ApiKeyAuthenticator
arguments: [ "@acme.demo.apikey_userprovider" ]
service.xml中:
<services>
<service id="acme.demo.apikey_userprovider" class="Acme\DemoBundle\Entity\UserinfoRepository" factory-service="doctrine.orm.entity_manager" factory-method="getRepository">
<argument>AcmeDemoBundle:Userinfo</argument>
</service>
<service id="acme.demo.apikey_authenticator" class="Acme\DemoBundle\Security\ApiKeyAuthenticator">
<argument type="service" id="acme.demo.apikey_userprovider" />
</service>
</services>
答案 5 :(得分:0)
Symfony 3.3 和 doctrine-bundle 1.8 有一个 Doctrine \ Bundle \ DoctrineBundle \ Repository \ ContainerRepositoryFactory 这有助于将存储库创建为服务。
我们想要什么
$rep = $kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository(Brand::class);
ORM说明
# Brand.orm.yaml
...
repositoryClass: App\Repository\BrandRepository
...
服务说明
# service.yaml
App\Repository\BrandRepository:
arguments:
- '@doctrine.orm.entity_manager'
- '@=service("doctrine.orm.entity_manager").getClassMetadata("App\\Entity\\Brand")'
tags:
- { name: doctrine.repository_service }
calls:
- method: setDefaultLocale
arguments:
- '%kernel.default_locale%'
- method: setRequestStack
arguments:
- '@request_stack'
答案 6 :(得分:-2)
sf 2.6 +
parameters:
mytest.entity: TestTestBundle:Brand
mytest.class: Test\TestBundle\Entity\Brand
default_repository.class: Doctrine\ORM\EntityRepository
services:
myservice:
class: %default_repository.class%
factory: ["@doctrine.orm.default_entity_manager", "getRepository"]
arguments:
- %mytest.entity%