토마스 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를 사용합니다).
$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/*');
그리고 cange ./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
.