Symfony 2: создание службы из репозитория
Я изучаю Symfony, и я пытаюсь создать сервис, используя repository. Я создал свои репозитории и сущности из 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%
Но когда я пытаюсь вызвать службу, я получаю эту ошибку:
- Как получить реальный размер базы данных MySQL?
- Как обрабатывать потерянный пароль KeyStore в Android?
- Как работает jQuery .data ()?
- Как создать файл на внутреннем хранилище Android?
- Android: я потерял свой магазин ключей для Android, что мне делать?
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
Кто-нибудь знает, что я делаю неправильно?
благодаря
- Ограничения Android SharedPreferences?
- Хранилище типов данных типа C ++
- как проверить внутреннее и внешнее хранилище, если они существуют
- Как управляются, реализуются, распределяются кучи и стеки памяти?
- Как вернуть пользовательский объект из запроса Spring JPA GROUP BY
- Как создать хранилище ключей?
- Настройка Eclipse для использования подписанного хранилища ключей
- Выполнение хранимой процедуры SQL и обработка результатов
Вот как мы это сделали в 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 позволяет переопределить фабрику репозитория по умолчанию.
Вот возможный способ реализовать его в 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%
Новый метод setFactory () был введен в Symfony 2.6. Обратитесь к старым версиям синтаксиса для фабрик до 2.6.
http://symfony.com/doc/2.7/service_container/factories.html
EDIT: Похоже, они продолжают меняться, так как 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. Ваша первая конфигурация работает отлично для меня, используя
- factory_service вместо заводского обслуживания
- factory_method вместо заводского метода
С 2017 года и Symfony 3.3+ это стало намного проще.
Примечание. Старайтесь избегать общих команд, таких как generate:entity
. Они предназначены для начинающих, чтобы сделать работу над проектом быстрой. Они склонны огорчать плохую практику и очень долго менять.
Проверьте мое сообщение Как использовать repository с Doctrine as Service в Symfony для более общего описания.
К вашему коду:
1. Обновите регистрацию конфигурации, чтобы использовать автоматическую регистрацию на основе PSR-4
# app/config/services.yml services: _defaults: autowire: true Test\TestBundle\: resource: ../../src/Test/TestBundle
2. Состав над наследством. Создайте собственный repository без прямой зависимости от Доктрины.
repository = $entityManager->getRepository(Brand::class); } public function findAll() { return $this->repository->findAll(); } }
3. Использование в любой службе или controllerе через инъекцию конструктора
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(); // ... } }
Я конвертирую service.yml в service.xml и обновляю DependencyInjection Extension, все работает для меня. Я не знаю, почему, но yml config будет выброшен Catchable Fatal Error. Вы можете попробовать использовать конфигурацию xml для конфигурации службы.
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:
AcmeDemoBundle:Userinfo
Symfony 3.3 и doctrine-bundle 1.8 существует Doctrine \ Bundle \ DoctrineBundle \ Repository \ ContainerRepositoryFactory, который помогает создавать repository в качестве службы.
пример
Что мы хотим
$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'
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%