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_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%
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%