Domanda

Quando leggo documenti sui repository, è spesso quello di lavorare con entità e raccolta ma in modo "di sola lettura".

Non ci sono mai esempi in cui i repository hanno metodi come insertUser(User $user) o updateUser(User $user).

Tuttavia, quando si utilizza SOA, il servizio non dovrebbe lavorare con Entity Manager (è vero, non è vero?) Quindi:

  1. Il mio servizio dovrebbe essere a conoscenza dell'EntityManager globale?
  2. Il mio servizio dovrebbe sapere solo dei repository usati (diciamo, UserRepository & ArticleRePository)

Da queste domande, un'altra, se il mio servizio dovrebbe mai esplicitamente persist() & flush() le mie entità?

È stato utile?

Soluzione

Sì, i repository sono generalmente utilizzati solo per le domande.

Ecco come lo faccio. Il livello di servizio gestisce la persistenza. Il livello del controller è a conoscenza del livello di servizio, ma non sa nulla di come gli oggetti del modello sono persistiti né da dove provengono. Per ciò che si preoccupa il livello del controller chiede al livello di servizio di persistere e restituire oggetti: non si preoccupa di come è effettivamente fatto.

Lo stesso livello di servizio è perfettamente adatto a conoscere il livello di persistenza: entità o gestori di documenti, repository, ecc.

Ecco un po 'di codice per renderlo più chiaro:

class UserController
{
    public function indexAction()
    {
        $users = $this->get('user.service')->findAll();
        // ...
    }

    public function createAction()
    {
        // ...
        $user = new User();
        // fill the user object here
        $this->get('user.service')->create($user);
        // ...
    }
}

class UserService
{
    const ENTITY_NAME = 'UserBundle:User';

    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function findAll()
    {
        return $this->em->getRepository(self::ENTITY_NAME)->findAll();
    }

    public function create(User $user)
    {
        // possibly validation here

        $this->em->persist($user);
        $this->em->flush($user);
    }
}

Altri suggerimenti

Se dai un'occhiata al modello di repository http://martinfowler.com/eaacatalog/repository.html ,

Si afferma che i repository utilizzano un'interfaccia simile a una raccolta ".

Successivamente, è anche scritto "Gli oggetti possono essere aggiunti e rimossi dal repository, come possono da una semplice raccolta di oggetti".

Non sto dicendo che questa sia una Bibbia, ma non c'è nulla di sbagliato nel vedere un repository come una raccolta che puoi interrogare. Ma dato che è una raccolta, puoi aggiungere, rimuovere, ... in effetti, l'objectrepository dovrebbe implementare la dottrina comune collezione :)

D'altra parte, il più importante è non confondere le letture e le scritture, come dice CQS. Questo è forse il motivo per cui non lo hanno permesso direttamente, di evitare abusi e leggere/scrivere mix.

EDIT: avrei dovuto parlare flush. Questo dovrebbe non essere realizzato nel repository stesso, in quanto potrebbe rompere la coerenza transazionale.

Faresti meglio a spostare il flush Chiama a qualcosa che avvolge l'intera logica delle transazioni commerciali (un bus di comando che gestisce un comando Fe?)

Bene, come si ottiene il tuo repository quando non si utilizza EntityManager? Dopotutto, le entità non verranno salvate magicamente senza una connessione al database, quindi il tuo servizio deve in qualche modo essere consapevole di qualsiasi tipo di connessione.

Non so dei servizi SOA, ma ai miei occhi non fa alcuna differenza se usi $_em->getRepository()->save($entity) o $_em->persist($entity). D'altra parte, se usi Flush nel tuo repository, potresti finire con molte più domande del necessario poiché il tuo repository è ora a conoscenza della logica aziendale.

Penso che ci sia un modo per fare questo "modo SOA", ma immagino che non stia persistendo le entità all'interno del repository.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top