Symfony - So greifen Sie auf das Repository der Entität zu

8

Es gibt mehrere Möglichkeiten, auf das Repository der Entität in Symfony2-Controllern oder -Services zuzugreifen, die jeweils ihren Vor- und Nachteil haben. Zuerst liste ich sie hier auf und frage dann, ob es eine bessere Lösung gibt oder das sind die einzigen Optionen, die wir haben, und wir sollten eine oder einige basierend auf unseren Präferenzen wählen. Ich möchte auch wissen, ob Methode 5 (die ich vor kurzem verwendet habe) gut sein kann und keine Regel bricht oder irgendwelche Nebenwirkungen hat.

Grundlegende Methode: Verwenden Sie den Entitätsmanager im Controller oder Injizieren Sie ihn in einen Service und greifen Sie dann auf ein beliebiges Repository zu. Dies ist die grundlegende Methode für den Zugriff auf ein Repository in einem Controller oder Service.

%Vor%

Aber es gibt einige Probleme im Zusammenhang mit diesem Verfahren. Das erste Problem ist, dass ich nicht Strg + Klick auf zum Beispiel loadProduct Funktion tun und direkt zu seiner Implementierung gehen kann (Es sei denn, es gibt eine Möglichkeit, die ich nicht kenne). Das andere Problem ist, dass ich diesen Teil des Codes immer und immer wieder wiederholen werde.

Methode 2: Die andere Methode besteht darin, einen Getter in meinem Dienst oder Controller zu definieren, um auf mein Repository zuzugreifen.

%Vor%

Diese Methode löst das erste Problem und irgendwie die zweite aber ich habe noch Um alle Getter zu wiederholen, die ich in meinem Service oder Controller benötige, werde ich mehrere Getter in meinen Diensten und Controllern haben, nur um auf Repositories zuzugreifen

Methode 3: Eine andere Möglichkeit besteht darin, ein Repository in meinen Service zu integrieren. Das ist besonders dann sinnvoll, wenn wir unseren Code gut kontrollieren und nicht mit anderen Entwicklern zusammenarbeiten, die den gesamten Container injizieren in Ihren Dienst.

%Vor%

Diese Methode löst das erste und zweite Problem, aber wenn mein Service groß ist und es muss mit vielen Repositories umgehen, dann ist es keine gute Idee spritze zum Beispiel 10 Repository in meinen Dienst.

Methode 4: Eine andere Möglichkeit besteht darin, einen Dienst zu verwenden, der alle meine Repositorys umschließt und diesen Dienst anderen Diensten hinzufügt.

%Vor%

RepositoryService:

%Vor%

Diese Methode löst auch das erste und zweite Problem. Aber RepositoryService kann so groß werden, wenn wir beispielsweise 200 Entitäten haben.

Methode 5: Schließlich kann ich eine statische Methode in jeder Entität definieren, die ihr Repository zurückgibt.

%Vor%

Meine Entität:

%Vor%

Diese Methode löst das erste und zweite Problem, ich muss auch kein a definieren Service für den Zugriff auf Repositories. Ich habe es kürzlich benutzt und bis jetzt ist es die beste Methode für mich. Ich glaube nicht, dass diese Methode die Regel von Entitäten brechen wird, da sie im Klassenumfang definiert ist und auch so ist. Aber ich bin mir immer noch nicht sicher darüber und ob es irgendwelche Nebenwirkungen hat oder nicht.

    
Saman Shafigh 12.08.2015, 03:55
quelle

3 Antworten

7

In der Doktrin-Welt soll die Entität nur ein anämisches Modell von Gettern und Setter sein (und hinzufügen oder entfernen), also wäre es falsch, das Repository zu injizieren.

Es hängt alles davon ab, wie stark du mit Doctrine verbunden sein willst. Wenn es Ihnen gelingt, den Dienst @doctrine herumzugeben, können Sie einfach etwas wie:

verwenden %Vor%

.. aber das würde, wie bereits erwähnt, dazu führen, dass Sie den Dienst @doctrine an jedes Objekt übergeben. Dies würde bedeuten, dass Sie, wenn Sie sich aus irgendeinem Grund dafür entschieden haben, Doctrine nicht zu verwenden, Ihren gesamten Code so umgestalten müssen, dass er zu Ihrer neuen Methodik passt (was auch immer das sein mag), aber dies kann für Sie kein Problem sein. Außerdem wird das Repository typisiert, so dass es keine Sicherheit gibt (neben der Überprüfung, ob es sich um die richtige Klasse im Code handelt), um sicherzustellen, dass es sich um den richtigen Dienst handelt.

Meiner Meinung nach ist es am saubersten, einen Service wie:

zu erstellen

XML

%Vor%

YAML

%Vor%

.. und dann können Sie Ihren Repository-Service überall hin mitnehmen, wo immer Sie möchten, ohne den Doktrin-Service in Ihrem eigentlichen Code verwenden zu müssen. Bei dieser Vorgehensweise müssen Sie, wenn Sie sich jemals von Doctrine entfernen, nur die Servicedefinitionen ändern, anstatt alles neu zu definieren. Aufgrund der Tatsache, dass Sie den Service Ihres spezifischen Repositories erstellen, können Sie type hinting in Ihrem __construct verwenden, um zu garantieren, dass der richtige Service wie folgt injiziert wird:

%Vor%     
qooplmao 12.08.2015 09:25
quelle
2

Für mich stimmt keiner Ihrer Vorschläge.
Weil ich nicht verstehe, warum Sie einen Dienst Ihrer Entität erstellen müssen.
Wenn Sie Zugang zu dieser Entität benötigen, brauchen Sie nur Zugang zur Doktrin.
Und die Lehre hat einen Dienst (@doctrine).
Es liegt an Ihnen, sich im Konstrukt darauf vorzubereiten, nur auf diese Entität Zugriff zu haben.

Statik ist zu vergessen:

Und was Sie in Methode 5 angeben, ist nicht korrekt. Ihre Product-Entität hat über ProductRepository bereits Zugriff auf den EntityManager mit der getEntityManager () -Methode.

    
Roukmoute 12.08.2015 07:03
quelle
1

Ich schlage vor, Sie verwenden Methode 4, Ihr Dienst wird Single Responability Principe folgen, da es nur eine Sache macht: Ihnen Zugang zu all Ihren Repositories zu geben.

Dieser Dienst wird hauptsächlich als Abhängigkeit in anderen Diensten verwendet. Für Controller empfehle ich Ihnen, eine benutzerdefinierte Controller-Basisklasse mit den gleichen Hilfsfunktionen zu erstellen.

Über Code-Duplikationen können Eigenschaften die Lösung sein. Auch bei der Anzahl der Methoden, wenn Sie ein Merkmal nach "Kategorie" verwenden

    
Yassine Guedidi 12.08.2015 22:40
quelle