Ich frage mich, wie ich meine Repositorys gruppieren soll. Wie aus den Beispielen, die ich auf dem asp.net mvc und in meinen Büchern gesehen habe, wird grundsätzlich ein Repository pro Datenbanktabelle verwendet. Aber das scheint eine Menge Repositories zu sein, die dazu führen, dass Sie später viele Repositories zum Verspotten und so weiter aufrufen müssen.
Also denke ich, ich sollte sie gruppieren. Ich bin mir jedoch nicht sicher, wie ich sie gruppieren soll.
Im Moment habe ich ein Registrierungs-Repository erstellt, um alle meine Registrierungsaufgaben zu erledigen. Es gibt jedoch ungefähr 4 Tabellen, die ich aktualisieren muss und bevor ich 3 Repositorys hatte, um dies zu tun.
Eine der Tabellen ist beispielsweise eine Lizenztabelle. Wenn sie sich registrieren, schaue ich auf ihren Schlüssel und überprüfe ihn, ob er in der Datenbank vorhanden ist. Was passiert nun, wenn ich diesen Lizenzschlüssel oder etwas anderes aus dieser Tabelle an einer anderen Stelle als der Registrierung überprüfen muss?
Ein Punkt könnte die Anmeldung sein (prüfen Sie, ob der Schlüssel nicht abgelaufen ist).
Was würde ich in dieser Situation tun? Code erneut umschreiben (DRY brechen)? Versuchen Sie, diese beiden Repositorys zusammenzufassen, und hoffen Sie, dass keine der Methoden zu einem anderen Zeitpunkt benötigt wird (z. B. könnte ich eine Methode haben, die überprüft, ob Benutzername verwendet wird - vielleicht brauche ich das woanders).
Auch wenn ich sie zusammenführe, würde ich entweder 2 Service-Layer benötigen, die in dasselbe Repository gehen, da ich denke, dass die gesamte Logik für 2 verschiedene Teile einer Site lang wäre und ich Namen wie ValidateLogin (), ValdiateRegistrationForm () haben müsste. , ValdiateLoginRetrievePassword () und etc.
Oder rufen Sie das Repository trotzdem an und haben Sie nur einen seltsam klingenden Namen?
Es scheint nur schwierig zu sein, ein Repository zu erstellen, dessen Name allgemein genug ist, damit Sie es für viele Stellen Ihrer Anwendung verwenden können und dennoch sinnvoll sind. Ich denke nicht, dass das Aufrufen eines anderen Repositorys in einem Repository eine gute Vorgehensweise wäre.
quelle
Antworten:
Eine Sache, die ich falsch gemacht habe, als ich mit dem Repository-Muster herumgespielt habe - genau wie Sie dachte ich, dass sich die Tabelle auf das Repository 1: 1 bezieht. Wenn wir einige Regeln aus Domain Driven Design anwenden, verschwindet das Problem der Gruppierung von Repositorys häufig.
Das Repository sollte sich im Aggregatstamm und nicht in der Tabelle befinden. Dies bedeutet, dass - wenn eine Entität nicht alleine leben sollte (dh wenn Sie eine Person haben, die
Registrant
insbesondere teilnimmtRegistration
) - es sich nur um eine Entität handelt, kein Repository benötigt, sondern über das Repository des aggregierten Stamms aktualisiert / erstellt / abgerufen werden sollte gehört.Natürlich kann in vielen Fällen diese Technik zum Reduzieren der Anzahl von Repositorys (eigentlich - es ist eher eine Technik zum Strukturieren Ihres Domänenmodells) nicht angewendet werden, da jede Entität eine aggregierte Wurzel sein soll (die stark von Ihrer Domäne abhängt). Ich kann nur blinde Vermutungen anstellen. In Ihrem Beispiel -
License
scheint eine aggregierte Wurzel zu sein, da Sie sie ohneRegistration
Entitätskontext überprüfen müssen müssen .Dies beschränkt uns jedoch nicht auf kaskadierte Repositorys (das
Registration
Repository darfLicense
bei Bedarf auf das Repository verweisen ). Dies beschränkt uns nicht darauf, dasLicense
Repository (vorzugsweise über IoC) direkt vomRegistration
Objekt aus zu referenzieren .Versuchen Sie einfach, Ihr Design nicht durch Komplikationen durch Technologien oder Missverständnisse voranzutreiben. Das Gruppieren von Repositorys,
ServiceX
nur weil Sie keine zwei Repositorys erstellen möchten, ist keine gute Idee.Viel besser wäre es, ihm einen richtigen Namen zu geben -
RegistrationService
dhDienste sollten jedoch generell vermieden werden - sie sind häufig Ursachen, die zu einem anämischen Domänenmodell führen .
BEARBEITEN:
Beginnen Sie mit der Verwendung von IoC. Es lindert wirklich den Schmerz, Abhängigkeiten zu injizieren.
Anstatt zu schreiben:
Sie können schreiben:
Ps Wäre besser, den sogenannten Common Service Locator zu verwenden, aber das ist nur ein Beispiel.
quelle
Eine Sache, die ich begonnen habe, um dies zu beheben, ist die Entwicklung von Diensten, die N Repositorys umschließen. Hoffentlich können Ihre DI- oder IoC-Frameworks dazu beitragen, dies zu vereinfachen.
Ist das sinnvoll? Ich verstehe auch, dass das Sprechen von Diensten in diesem Herrenhaus möglicherweise tatsächlich den DDD-Grundsätzen entspricht oder nicht. Ich mache es einfach, weil es zu funktionieren scheint.
quelle
Ich habe eine abstrakte Basisklasse, die wie folgt definiert ist:
Sie können dann Ihr Repository von der abstrakten Basisklasse ableiten und Ihr einzelnes Repository erweitern, solange sich die generischen Argumente beispielsweise unterscheiden.
etc....
Ich benötige die separaten Repositorys, da wir für einige unserer Repositorys Einschränkungen haben und dies uns maximale Flexibilität gibt. Hoffe das hilft.
quelle
Ich habe dies als meine Repository-Klasse und ja, ich erweitere das Tabellen- / Bereichs-Repository, aber manchmal muss ich DRY trotzdem brechen.
BEARBEITEN
Ich habe auch einen Datenkontext, der mit der Klasse Linq2SQL.dbml erstellt wurde.
Jetzt habe ich ein Standard-Repository, das Standardaufrufe wie All and Find implementiert, und in meinem AdminRepository habe ich bestimmte Aufrufe.
Beantwortet die Frage von DRY nicht, obwohl ich nicht denke.
quelle
Hier ist ein Beispiel für eine generische Repository-Implementierung mit FluentNHibernate. Es kann jede Klasse beibehalten, für die Sie einen Mapper geschrieben haben. Es ist sogar in der Lage, Ihre Datenbank basierend auf den Mapper-Klassen zu generieren.
quelle
Das Repository-Muster ist ein schlechtes Entwurfsmuster. Ich arbeite mit vielen alten .Net-Projekten und dieses Muster verursacht normalerweise "Distributed Transactions" -, "Partial Rollback" - und "Connection Pool Exhausted" -Fehler, die vermieden werden könnten. Das Problem ist, dass das Muster versucht, Verbindungen und Transaktionen intern zu verarbeiten, diese sollten jedoch auf der Controller-Ebene behandelt werden. Auch EntityFramework abstrahiert bereits einen Großteil der Logik. Ich würde vorschlagen, stattdessen das Dienstmuster zu verwenden, um gemeinsam genutzten Code wiederzuverwenden.
quelle
Ich empfehle Ihnen, sich Sharp Architecture anzuschauen . Sie schlagen vor, ein Repository pro Entität zu verwenden. Ich verwende es derzeit in meinem Projekt und bin sehr zufrieden mit den Ergebnissen.
quelle