Cómo decorar nuestros repositorios en Symfony

El patrón “decorador” aplicado a los repositorios de Doctrine de Symfony

Image for post
Image for post

Favorece la composición frente a la herencia

Descripción del problema

class RepositoryA {  public function findTodayStats(): int {    $today = new \DateTime();    return $this->createQueryBuilder('o')      ->select('COUNT(o) as total')      ->andWhere('o.createdAt = :today')      ->setParameter('today', $today)      ->getQuery()      ->getSingleScalarResult();    ;  }}

Solución con herencia

class ParentRepository {  public function findTodayStats(): int {    $today = new \DateTime();    return $this->createQueryBuilder('o')      ->select('COUNT(o) as total')      ->andWhere('o.createdAt = :today')      ->setParameter('today', $today)      ->getQuery()      ->getSingleScalarResult();    ;  }}class RepositoryA extends ParentRepository { // }class RepositoryB extends ParentRepository { // }

El patrón decorador

Vale muy bien, pero… ¿y ahora cómo empleamos este repositorio decorado?

use App\Repository\RepositoryA;class AnyService {  public function __construct(RepositoryA $repo) {

$this->repo = $repo
} .... // rest
app.repository.a.stats:  class: App\Repository\EntityStatsRepositoryDecorator  decorates: App\Repository\RepositoryA  // no necesario a partir de Symfony 4.2  arguments:    $repository: '@app.repository.a.stats.inner'
App\Service\AnyService

arguments:
$repo: '@app.repository.a.stats'
services:  _defaults:    autowire: true    autoconfigure: true    bind:      $aRepoWithStats: '@app.repository.a.stats'
use App\Repository\RepositoryA;class AnyService {public function __construct(ServiceEntityRepository $aRepoWithStats) {

$this->repo = $aRepoWithStats
}.... // rest
app.repository.b.stats:  class: App\Repository\EntityStatsRepositoryDecorator  decorates: App\Repository\RepositoryB  arguments:    $repository: '@app.repository.b.stats.inner'
bind:  $bRepoWithStats: '@app.repository.b.stats'

¿Quieres recibir más artículos como este?

Written by

Entre paseo y paseo con Simba desarrollo en Symfony y React

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store