Frage

Wenn ich Dokumente über Repositories lese, ist es oft, mit Entitäten und Sammlung zu arbeiten, aber auf "schreibgeschützte" Weise.

Es gibt nie Beispiele, in denen Repositorys Methoden wie vorhanden sind insertUser(User $user) oder updateUser(User $user).

Bei der Verwendung von SOA sollte der Service jedoch nicht mit dem Entitätsmanager zusammenarbeiten (das ist richtig, nicht wahr?) Also:

  1. Sollte sich mein Dienst über den globalen EntityManager bewusst sein?
  2. Sollte mein Dienst nur über die gebrauchten Repositorys wissen (sagen wir, userrepository & articlerepository)

Aus diesen beiden Fragen sollte mein Dienst jemals explizit explizit persist() & flush() meine Einheiten?

War es hilfreich?

Lösung

Ja, Repositorys werden im Allgemeinen nur für Abfragen verwendet.

So mache ich es. Das Serviceschicht verwaltet die Persistenz. Die Controller -Ebene weiß die Serviceschicht, weiß aber nichts darüber, wie die Modellobjekte bestehen bleiben, oder woher sie kommen. Für das, was die Controller -Ebene kümmert, bittet es die Servicestand, Objekte zu bestehen und zurückzugeben - es ist es egal, wie sie tatsächlich gemacht wird.

Die Serviceschicht selbst ist perfekt geeignet, um die Persistenzschicht zu kennen: Entitäts- oder Dokumentmanager, Repositories usw.

Hier ist ein Code, um es klarer zu machen:

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);
    }
}

Andere Tipps

Wenn Sie sich das Repository -Muster ansehen http://martinfowler.com/eaacatalog/repository.html ,

Es wird angegeben, dass Repositories eine "sammelähnliche Schnittstelle" verwenden.

Später lautet es auch "Objekte können aus dem Repository aus einer einfachen Sammlung von Objekten aus dem Repository hinzugefügt und entfernt werden."

Ich sage nicht, dass dies eine Bibel ist, aber es gibt konzeptionell nichts Falsches, ein Repository wie eine Sammlung zu sehen, die Sie abfragen können. Aber da es sich um eine Sammlung handelt, können Sie, ... Tatsächlich sollten Sie die Doktrin Common Collection hinzufügen, die Objektecrepository implementieren :)

Auf der anderen Seite ist das Wichtigste nicht, Lese- und Schreibvorgänge zu durcheinander, wie CQS sagt. Das ist vielleicht der Grund, warum sie das nicht direkt zugelassen haben, um Missbräuche zu vermeiden und Mix zu lesen/zu schreiben.

Bearbeiten: Ich hätte darüber sprechen sollen flush. Das sollte nicht im Repository selbst hergestellt werden, da es die transaktionale Konsistenz brechen kann.

Sie sollten das besser bewegen flush Rufen Sie etwas an, das die gesamte Geschäftstransaktionslogik umhüllt (ein Befehlsbus, der einen Befehl FE bearbeitet?)

Wie erhalten Sie Ihr Repository, wenn Sie den EntityManager nicht verwenden? Schließlich werden die Entitäten ohne eine Verbindung zur Datenbank nicht magisch gespeichert, sodass sich Ihr Dienst irgendwie bewusst sein muss.

Ich weiß nichts über die SOA -Dienste, aber in meinen Augen macht es überhaupt keinen Unterschied, wenn Sie verwenden $_em->getRepository()->save($entity) oder $_em->persist($entity). Wenn Sie andererseits Flush in Ihrem Repository verwenden, werden Sie möglicherweise viel mehr Abfragen als benötigt, da Ihr Repository jetzt die Geschäftslogik kennen.

Ich denke, es gibt eine Möglichkeit, dies "den SOA -Weg" zu tun, aber ich denke, es besteht nicht an den Wesenheiten im Repository.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top