在我的案例中,基于@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实体定义一个服务,例如在我的情况下定义一个服务(我使用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
的嘲讽aither的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 }
然后,您可以按照以下方式使用该服务(在我使用的名为Dummy实体的示例中使用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
。