Während ich mich eingehender mit DbContext, DbSet und den zugehörigen Schnittstellen befasse, frage ich mich, warum Sie für diese Implementierungen ein separates "generisches" Repository implementieren müssten.
Es sieht so aus, als ob DbContext und IDbSet alles tun, was Sie brauchen, und die "Arbeitseinheit" in DbContext aufnehmen.
Vermisse ich hier etwas oder scheint es den Leuten Spaß zu machen, ohne Grund eine weitere Abhängigkeitsebene hinzuzufügen?
repository-pattern
entity-framework-4.1
unit-of-work
Code Jammr
quelle
quelle
Antworten:
Du hast tatsächlich recht.
DbContext
ist eine Implementierung des Arbeitseinheitsmusters undIDbSet
eine Implementierung des Repository-Musters.Repositories sind derzeit sehr beliebt und werden häufig verwendet. Jeder verwendet sie nur, weil es Dutzende von Artikeln zum Erstellen eines Repositorys für das Entity-Framework gibt, aber niemand beschreibt tatsächlich die Herausforderungen im Zusammenhang mit dieser Entscheidung.
Hauptgründe für die Verwendung des Repositorys sind normalerweise:
Der erste Grund ist eine Art architektonische Reinheit und eine großartige Idee, dass Sie später zu einem anderen Persistenz-Framework wechseln können, wenn Sie Ihre oberen Schichten von EF unabhängig machen. Wie oft haben Sie so etwas in der realen Welt gesehen? Dieser Grund erschwert die Arbeit mit EF erheblich, da Ihr Repository viele zusätzliche Funktionen bereitstellen muss, die das einschließen, was EF standardmäßig zulässt.
Gleichzeitig kann das Umschließen von EF-Code Ihren Code besser organisieren und die Regel der Trennung von Bedenken befolgen. Für mich kann dies der einzige wirkliche Vorteil von Repository und Arbeitseinheit sein, aber Sie müssen verstehen, dass das Befolgen dieser Regel mit EF Ihren Code möglicherweise besser wartbar und besser lesbar macht, aber bei den anfänglichen Bemühungen, Ihre Anwendung zu erstellen, viel höher und höher ist Für kleinere Anwendungen kann dies eine unnötige Komplexität sein.
Der zweite Grund ist teilweise richtig. Der große Nachteil von EF ist die starre Architektur, die kaum verspottet werden kann. Wenn Sie also die obere Schicht als Unit-Test durchführen möchten, müssen Sie EF irgendwie umschließen, damit die Implementierung verspottet werden kann. Dies hat aber noch viele andere Konsequenzen, die ich hier beschrieben habe .
Ich folge Ayendes Blog . Wenn Sie jemals NHibernate verwendet haben, kennen Sie wahrscheinlich seine Artikel. Dieser Typ hat kürzlich mehrere Artikel gegen die Verwendung von Repository mit NHibernate geschrieben, aber NHibernate ist viel besser verspottbar.
quelle
IDbSet
Sie können auch eine benutzerdefinierte Schnittstelle in Ihrem abgeleiteten Kontext definieren, aber das ist alles. Sobald Ihr Code ChangeTracker, Einträge oder was auch immer verwendet, wird es einen großen Aufwand erfordern, sie alle zu verpacken.IQueryable
oderExpression<>
als Parameter akzeptiert , der intern in die Linq-to-Entities-Abfrage gestellt wird, definieren Sie eine Logik außerhalb der verspotteten Komponente mit Nebenwirkungen, die nicht mit Komponententests getestet werden können.Ich habe mit den gleichen Problemen zu kämpfen, und die Verspottbarkeit beim Testen der EF-Schichten ist wichtig. Ich bin jedoch auf diesen großartigen Artikel gestoßen, in dem erklärt wird, wie der EF 4.1 DbContext so eingerichtet wird, dass er verspottbar ist, indem sichergestellt wird, dass Ihr abgeleiteter DbContext eine generische Schnittstelle implementiert und IDbSet anstelle von DbSet verfügbar macht. Da ich einen Database First-Ansatz verwende, da unsere Datenbank bereits vorhanden ist, habe ich einfach die T4-Vorlagen geändert, die zum Generieren meines abgeleiteten DbContext verwendet wurden, um ihn zu generieren, um IDbSet-Schnittstellen zurückzugeben und von meiner generischen Schnittstelle abzuleiten. Auf diese Weise kann das Ganze leicht verspottet werden, und Sie müssen kein eigenes Arbeitseinheits- oder Repository-Muster implementieren. Schreiben Sie einfach Ihren Service-Code, um Ihre generische Schnittstelle zu nutzen, und wenn Sie zum Unit-Test gehen,
http://refactorthis.wordpress.com/2011/05/31/mock-faking-dbcontext-in-entity-framework-4-1-with-a-generic-repository/
quelle
Ein Grund für das Erstellen des Repositorys besteht darin, dass Sie die Implementierung von DBSet und DbContext ausblenden können, wenn Sie von EntityFramework zu etwas anderem wechseln oder umgekehrt.
Ich habe beispielsweise NHibernate verwendet und alle Aufrufe dieses Frameworks in meine Repository-Klassen eingeschlossen. Sie geben IEnumerable zurück, damit sie "generisch" werden, und meine Repositorys verfügen über die Standard-CRUD-Operationen (Aktualisieren, Löschen usw.). Ich bin längst zu Entity Framework gewechselt. Dabei musste ich in meinen ViewModel-Klassen oder darüber hinaus nichts mehr ändern, da sie auf mein Repository verweisen. Ich musste nur das Innere meines Repositorys ändern. Dies erleichterte das Leben bei der Migration erheblich.
(Ich habe NHibernate verwendet, weil wir eine Verbindung zu den ISeries herstellen, und zu diesem Zeitpunkt gab es keine kosteneffektiven Implementierungen mit EF mit den ISeries. Die einzige verfügbare war, IBM 12.000 US-Dollar für ihren DB2Connect zu zahlen.)
quelle