Symfony 2:从存储库创build一个服务

我正在学习Symfony,我一直在尝试使用存储库来创build一个服务。 我已经从generate:entity创build了我的仓库和实体,所以他们应该没问题。

到目前为止,我在我的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 

然后我试图用一个实体来创build这个服务。 我的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 

有人知道我在做什么错吗?

谢谢

下面是我们如何在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% ] 

UPDATE

自2.4以来,教条允许覆盖默认的存储器工厂。

这是一个可以在symfony中实现的方法: https : //gist.github.com/docteurklein/9778800

弃权警告:不再有factory_servicefactory_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% 

Symfony 2.6引入了新的setFactory()方法。 请参阅旧版本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

您可能使用了错误的YAML-Keys。 你的第一个configuration适合我使用

  • factory_service而不是工厂服务
  • factory_method而不是factory-method

我将service.yml转换为service.xml,并更新DependencyInjection扩展,一切都为我工作。 我不知道为什么,但是yml config会抛出Catchable致命错误。 您可以尝试使用xmlconfiguration进行服务configuration。

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> 

从2017年和Symfony 3.3+这现在更容易。

注意:尽量避免像generate:entity这样的通用命令。 他们是为了让项目工程师快速工作而devise的。 他们倾向于做坏习惯,花费很长时间来改变。

检查我的post如何在Symfony中使用Repository与Doctrine作为服务来获得更为一般的描述。

给你的代码:

1.更新您的configuration注册以使用基于PSR-4的自动注​​册

 # app/config/services.yml services: _defaults: autowire: true Test\TestBundle\: resource: ../../src/Test/TestBundle 

2.inheritance构成 – 创build自己的存储库,不直接依赖于学说

 <?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(); } } 

3.通过构造函数注入在任何服务或控制器中使用

 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(); // ... } } 

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%