У моєму випадку на основі відповіді @ Tomáš Votruba і цього питання я пропоную такі підходи:
Адаптерний підхід
Без спадщини
Створіть загальний клас адаптера:
namespace AppBundle\Services;
use Doctrine\ORM\EntityManagerInterface;
class RepositoryServiceAdapter
{
private $repository=null;
public function __construct(EntityManagerInterface $entityManager,$entityName)
{
$this->repository=$entityManager->getRepository($entityName)
}
public function __call($name,$arguments)
{
if(empty($arrguments)){
$this->repository->$name();
} else {
$this->repository->$name(...$argument);
}
}
}
Потім foreach entity Визначте послугу, наприклад у моєму випадку для визначення a (я використовую php для визначення служб symfony):
$container->register('ellakcy.db.contact_email',AppBundle\Services\Adapters\RepositoryServiceAdapter::class)
->serArguments([new Reference('doctrine'),AppBundle\Entity\ContactEmail::class]);
З успадкуванням
Той самий крок 1, згаданий вище
Розширити RepositoryServiceAdapter
клас, наприклад:
namespace AppBundle\Service\Adapters;
use Doctrine\ORM\EntityManagerInterface;
use AppBundle\Entity\ContactEmail;
class ContactEmailRepositoryServiceAdapter extends RepositoryServiceAdapter
{
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($entityManager,ContactEmail::class);
}
}
Послуга реєстрації:
$container->register('ellakcy.db.contact_email',AppBundle\Services\Adapters\RepositoryServiceAdapter::class)
->serArguments([new Reference('doctrine')]);
У будь-якому випадку у вас є хороший тестований спосіб перевірки поведінки бази даних, а також це допомагає вам знущатися на випадок, якщо ви хочете перевірити модуль своєї служби без необхідності занадто турбуватися про те, як це зробити. Наприклад, припустимо, що ми маємо таку послугу:
class MyDummyService
{
public function __construct(RepositoryServiceAdapter $adapter)
{
}
}
А RepositoryServiceAdapter адаптує наступне сховище:
class SomeRepository extends \Doctrine\ORM\EntityRepository
{
public function search($params)
{
}
}
Тестування
Таким чином, ви можете легко знущатись / жорстко кодувати / емулювати поведінку методу, search
визначеного в SomeRepository
, знущаючись над підходом, що RepositoryServiceAdapter
не успадковується, або над методом ContactEmailRepositoryServiceAdapter
успадкування.
Заводський підхід
Ви також можете визначити таку фабрику:
namespace AppBundle\ServiceFactories;
use Doctrine\ORM\EntityManagerInterface;
class RepositoryFactory
{
public static function repositoryAsAService(EntityManagerInterface $entityManager,$entityName)
{
return $entityManager->getRepository($entityName);
}
}
А потім перейдіть до анотації служби php, виконавши наступне:
Помістіть це у файл ./app/config/services.php
(для symfony v3.4 .
передбачається корінь вашого ptoject)
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
$definition = new Definition();
$definition->setAutowired(true)->setAutoconfigured(true)->setPublic(false);
$this->registerClasses($definition, 'AppBundle\\', '../../src/AppBundle/*', '../../src/AppBundle/{Entity,Repository,Tests,Interfaces,Services/Adapters/RepositoryServiceAdapter.php}');
$definition->addTag('controller.service_arguments');
$this->registerClasses($definition, 'AppBundle\\Controller\\', '../../src/AppBundle/Controller/*');
І помістити ./app/config/config.yml
( .
передбачається корінь вашого ptoject)
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.php }
Тоді ви можете скористатися службою наступним чином (використано з мого прикладу, коли я використовував фіктивну сутність Item
):
$container->register(ItemRepository::class,ItemRepository::class)
->setFactory([new Reference(RepositoryFactory::class),'repositoryAsAService'])
->setArguments(['$entityManager'=>new Reference('doctrine.orm.entity_manager'),'$entityName'=>Item::class]);
Також як загальна порада, перехід на php
службову анотацію дозволяє виконувати безпроблемну, вдосконалену конфігурацію служби, наведену вище. Для фрагментів коду використовуйте спеціальне сховище, яке я створив за допомогою factory
методу.