J'apprends Symfony et j'essaie de créer un service en utilisant un référentiel ..__ J'ai créé mes référentiels et mes entités à partir de generate: entity, donc tout devrait bien se passer.
Jusqu'à présent, ce que j'ai dans mon fichier services.yml est:
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%
Mais lorsque j'essaie d'appeler le service, j'obtiens cette erreur:
Catchable Fatal Error: Argument 2 passed to Doctrine\ORM\EntityRepository::__construct() must be an instance of Doctrine\ORM\Mapping\ClassMetadata, none given, called in
Ensuite, j'ai essayé de créer le service en utilisant simplement une entité. Mon services.yml ressemblerait à ceci:
services:
myservice:
class: %mytest.class%
factory-service: doctrine.orm.default_entity_manager
factory-method: getRepository
arguments:
- %mytest.entity%
Mais pour cela, je reçois:
Error: Call to undefined method
Test\TestBundle\Entity\Brand::findAll
Est-ce que quelqu'un sait ce que je fais mal?
Merci
Voici comment nous avons procédé dans KnpRadBundle: https://github.com/KnpLabs/KnpRadBundle/blob/develop/DependencyInjection/Definition/DoctrineRepositoryFactory.php#L9
Enfin, il devrait être:
my_service:
class: Doctrine\Common\Persistence\ObjectRepository
factory_service: doctrine # this is an instance of Registry
factory_method: getRepository
arguments: [ %mytest.entity% ]
METTRE À JOUR
Depuis la version 2.4, doctrine permet de remplacer la fabrique de référentiel par défaut.
Voici un moyen possible de l'implémenter dans symfony: https://Gist.github.com/docteurklein/9778800
AVERTISSEMENT DE DEPRECATION: Plus de factory_service
et factory_method
. Voici comment procéder depuis Symfony 2.6 (pour Symfony 3.3+, vérifiez ci-dessous):
parameters:
entity.my_entity: "AppBundle:MyEntity"
services:
my_entity_repository:
class: AppBundle\Repository\MyEntityRepository
factory: ["@doctrine", getRepository]
arguments:
- %entity.my_entity%
La nouvelle méthode setFactory () a été introduite dans Symfony 2.6. Reportez-vous aux anciennes versions pour la syntaxe des usines antérieures à 2.6.
http://symfony.com/doc/2.7/service_container/factories.html
EDIT: On dirait qu'ils changent constamment, donc depuis Symfony 3.3 il y a une nouvelle syntaxe:
# app/config/services.yml
services:
# ...
AppBundle\Email\NewsletterManager:
# call the static method
factory: ['AppBundle\Email\NewsletterManagerStaticFactory', createNewsletterManager]
Découvrez-le: http://symfony.com/doc/3.3/service_container/factories.html
Vous avez peut-être utilisé les mauvaises clés YAML. Votre première configuration fonctionne bien pour moi en utilisant
Depuis 2017 et Symfony 3.3+, cela est maintenant beaucoup plus facile.
Remarque: Essayez d'éviter les commandes génériques telles que generate:entity
. Elles sont destinées aux débutants pour que le projet fonctionne rapidement. Elles ont tendance à faire face aux mauvaises pratiques et prennent très longtemps à changer.
Check my post Comment utiliser Repository avec Doctrine as Service dans Symfony pour une description plus générale.
Pour votre code:
# 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();
// ...
}
}
Symfony 3.3 et doctrine-bundle 1.8 il existe un Doctrine\Bundle\DoctrineBundle\Repository\ContainerRepositoryFactory Qui permet de créer un référentiel en tant que service.
Ce que nous voulons
$rep = $kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository(Brand::class);
Description de l'ORM
# Brand.orm.yaml
...
repositoryClass: App\Repository\BrandRepository
...
Description du service
# 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'
Je convertis service.yml en service.xml et mets à jour DependencyInjection Extension. Je ne sais pas pourquoi, mais yml config lancera une erreur fatale capturable. Vous pouvez essayer d'utiliser xml config pour le service 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>