Lets say we have two Repository classes:
class CarrierRepository extends ServiceEntityRepository
{
const ENTITY = 'carrier';
/** @var PaginatorInterface $paginator */
private $paginator;
public function __construct(ManagerRegistry $registry, PaginatorInterface $paginator)
{
$this->paginator = $paginator;
parent::__construct($registry, Carrier::class);
}
.
.
.
class LocationRepository extends ServiceEntityRepository
{
const ENTITY = 'location';
/** @var PaginatorInterface $paginator */
private $paginator;
public function __construct(ManagerRegistry $registry, PaginatorInterface $paginator)
{
$this->paginator = $paginator;
parent::__construct($registry, Location::class);
}
.
.
.
And in both of these repository classes we have the same logic like this:
public function search(array $searchParams)
{
$parameters = [];
$qb = $this->createQueryBuilder(self::ENTITY);
foreach ($searchParams['data'] as $key => $searchParam) {
if (!empty($searchParam['param'])) {
$entity = self::ENTITY;
$operator = 'LIKE';
$column = $searchParam['key'];
$parameters[$searchParam['key']] = '%'.$searchParam['param'].'%';
.
.
.
As you can see, both Repository classes have the same dependencies and the same logic - except the entity class - in one class it is "carrier" and in the other it is "location". I think it will be a good idea to merge this into a BaseRepository class like this:
class BaseRepository extends ServiceEntityRepository
{
private $entity;
/** @var PaginatorInterface $paginator */
private $paginator;
public function __construct($entity, ManagerRegistry $registry, PaginatorInterface $paginator)
{
$this->entity = $entity;
$this->paginator = $paginator;
parent::__construct($registry, $this->entity);
}
public function search(array $searchParams)
{
$parameters = [];
$qb = $this->createQueryBuilder(self::ENTITY);
foreach ($searchParams['data'] as $key => $searchParam) {
if (!empty($searchParam['param'])) {
$entity = self::ENTITY;
$operator = 'LIKE';
$column = $searchParam['key'];
$parameters[$searchParam['key']] = '%'.$searchParam['param'].'%';
.
.
.
and to extend my other both repositories instead of
ServiceEntityRepository
with my BaseRepository like this (example for the CarrierRepository):
class CarrierRepository extends BaseRepository
{
const ENTITY = 'carrier';
/** @var PaginatorInterface $paginator */
private $paginator;
public function __construct(ManagerRegistry $registry, PaginatorInterface $paginator)
{
$this->paginator = $paginator;
parent::__construct(Carrier::class, $registry, $paginator);
}
.
.
.
This does not work - it will give me this error:
Cannot autowire service "App\Repository\BaseRepository": argument "$entity" of method "__construct()" has no type-hint, you should configure its value explicitly.
Question: How can I implement a BaseRepository for all my EntityRepositories that uses the same properties and logic, so I do not have to implement the whole logic in all my Repository classes again and again? I want to have a Base Repository in which is the whole logic and all of my Repository classes can use the same code.