I have a symfony/api-platform application which connects to 2 different databases configured in doctrine.yaml. I want to notice that both databases store the same entities (but with different actions on each), hence we duplicated all the entity classes and created a repository for each, in order for migrations and api-platform actions to work. Since those enities share a lot of common repository functionallity, what I have done so far to remove code duplication is:
Create entity manager decorators
class AEntityManager extends EntityManagerDecorator{}
class BEntityManager extends EntityManagerDecorator{}
config/services.yaml
App\EntityManager\AEntityManager:
decorates: doctrine.orm.a_entity_manager
App\EntityManager\BEntityManager:
decorates: doctrine.orm.b_entity_manager
App\Repository\Main\AResourceRepository:
arguments:
- '@App\EntityManager\AEntityManager'
App\Repository\ProductPending\BResourceRepository:
arguments:
- '@App\EntityManager\BEntityManager'
Create a base class (for each entity) to share code between the 2 repositories
class RepositoryBase extends ServiceEntityRepository
{
public function __construct(EntityManagerInterface $em, string $class) {...}
// common methods
}
class ARepository extends RepositoryBase
{
public function __construct(EntityManagerInterface $em)
{
parent::__construct($em, A::class);
}
}
class BRepository extends RepositoryBase
{
public function __construct(EntityManagerInterface $em)
{
parent::__construct($em, B::class);
}
}
And entities
/**
@Orm\Entity(repositoryClass=ARepository::class)
*/
class A {
string $prop;
}
/**
@Orm\Entity(repositoryClass=BRepository::class)
*/
class B {
string $prop;
}
Note that all actions for the second database occur in endpoints prefixed with (let's say) /api/b/...
I would like to know if there is a way to eliminate the different repository classes and define the same repository across the 2 different entities. What I have in mind is to change the object which is used to inject the EntityManagerInterface constructor parameter based on the url of the request, but I haven't found something specific about it and I don't know if that's even possible.