Das Repository-Muster ist eine Abstraktion . Ziel ist es, die Komplexität zu reduzieren und den Rest des Codes unwissend zu machen. Als Bonus können Sie Unit- Tests anstelle von Integrationstests schreiben .
Das Problem ist, dass viele Entwickler den Zweck des Musters nicht verstehen und Repositorys erstellen, die persistenzspezifische Informationen an den Aufrufer weitergeben (normalerweise durch Offenlegen IQueryable<T>
). Auf diese Weise erhalten sie keinen Vorteil gegenüber der direkten Verwendung des OP / M.
Update, um eine andere Antwort zu adressieren
Codierung für die Ausnahme
Bei der Verwendung von Repositorys geht es nicht darum, die Persistenztechnologie zu wechseln (dh die Datenbank zu ändern oder stattdessen einen Webservice usw. zu verwenden). Es geht darum, Geschäftslogik von Persistenz zu trennen, um Komplexität und Kopplung zu reduzieren.
Unit-Tests gegen Integrationstests
Sie schreiben keine Komponententests für Repositorys. Zeitraum.
Durch die Einführung von Repositorys (oder einer anderen Abstraktionsschicht zwischen Persistenz und Geschäft) können Sie jedoch Komponententests für die Geschäftslogik schreiben. Das heißt, Sie müssen sich keine Sorgen machen, dass Ihre Tests aufgrund einer falsch konfigurierten Datenbank fehlschlagen.
Wie für die Abfragen. Wenn Sie LINQ verwenden, müssen Sie auch sicherstellen, dass Ihre Abfragen funktionieren, genau wie Sie es mit Repositorys tun. und das geschieht mit Integrationstests.
Der Unterschied besteht darin, dass Sie, wenn Sie Ihr Unternehmen nicht mit LINQ-Anweisungen gemischt haben, zu 100% sicher sein können, dass Ihr Persistenzcode fehlschlägt und nicht etwas anderes.
Wenn Sie Ihre Tests analysieren, werden Sie auch feststellen, dass sie viel sauberer sind, wenn Sie keine gemischten Bedenken haben (z. B. LINQ + Geschäftslogik).
Repository-Beispiele
Die meisten Beispiele sind Bullshit. das ist sehr wahr. Wenn Sie jedoch ein Designmuster googeln, finden Sie viele beschissene Beispiele. Dies ist kein Grund, die Verwendung eines Musters zu vermeiden.
Das Erstellen einer korrekten Repository-Implementierung ist sehr einfach. In der Tat müssen Sie nur eine einzige Regel befolgen:
Fügen Sie der Repository-Klasse erst dann etwas hinzu, wenn Sie es benötigen
Viele Codierer sind faul und versuchen, ein generisches Repository zu erstellen und eine Basisklasse mit vielen Methoden zu verwenden, die sie möglicherweise benötigen. YAGNI. Sie schreiben die Repository-Klasse einmal und behalten sie so lange, wie die Anwendung lebt (kann Jahre sein). Warum es versauen, indem man faul ist? Halten Sie es sauber, ohne dass eine Basisklasse vererbt wird. Dies erleichtert das Lesen und Verwalten erheblich.
(Die obige Aussage ist eine Richtlinie und kein Gesetz. Eine Basisklasse kann sehr gut motiviert sein. Denken Sie einfach nach, bevor Sie sie hinzufügen, damit Sie sie aus den richtigen Gründen hinzufügen.)
Altes Zeug
Fazit:
Wenn es Ihnen nichts ausmacht, LINQ-Anweisungen in Ihrem Geschäftscode zu haben oder sich um Komponententests zu kümmern, sehe ich keinen Grund, Entity Framework nicht direkt zu verwenden.
Aktualisieren
Ich habe sowohl über das Repository-Muster als auch darüber gebloggt, was "Abstraktion" wirklich bedeutet: http://blog.gauffin.org/2013/01/repository-pattern-done-right/
Update 2
Wie werden Sie für einen einzelnen Entitätstyp mit mehr als 20 Feldern eine Abfragemethode entwerfen, um eine Permutationskombination zu unterstützen? Sie möchten die Suche nicht nur nach Namen einschränken. Wie wäre es mit der Suche mit Navigationseigenschaften? Listen Sie alle Bestellungen mit Artikeln mit einem bestimmten Preiscode auf. 3 Ebenen der Suche nach Navigationseigenschaften. Der ganze Grund, IQueryable
der erfunden wurde, war, in der Lage zu sein, eine beliebige Kombination von Suche gegen Datenbank zusammenzustellen. Theoretisch sieht alles gut aus, aber das Bedürfnis des Benutzers gewinnt über der Theorie.
Nochmals: Eine Entität mit mehr als 20 Feldern ist falsch modelliert. Es ist eine GOTTES Einheit. Mach es kaputt.
Ich behaupte nicht, dass IQueryable
das nicht zum Abfragen gemacht war. Ich sage, dass es für eine Abstraktionsschicht wie das Repository-Muster nicht richtig ist, da es undicht ist. Es gibt keinen 100% vollständigen LINQ To Sql-Anbieter (wie EF).
Sie alle haben implementierungsspezifische Dinge wie das eifrige Laden oder das Ausführen von SQL "IN" -Anweisungen. Das Offenlegen IQueryable
im Repository zwingt den Benutzer, all diese Dinge zu wissen. Somit ist der gesamte Versuch, die Datenquelle zu abstrahieren, ein völliger Fehlschlag. Sie erhöhen lediglich die Komplexität, ohne einen Vorteil gegenüber der direkten Verwendung des OP / M zu erzielen.
Implementieren Sie das Repository-Muster entweder korrekt oder verwenden Sie es überhaupt nicht.
(Wenn Sie wirklich mit großen Entitäten umgehen möchten, können Sie das Repository-Muster mit dem Spezifikationsmuster kombinieren . Dadurch erhalten Sie eine vollständige Abstraktion, die auch testbar ist.)