Repository-Muster Standardisierung der Methoden
Alle ich bin auf der Suche nach der richtigen definition der repository-pattern.
Meinem ursprünglichen Verständnis war diese (extrem verdummt)
- Trennen Sie Ihre Business-Objekte aus den Daten Objekte
- Standardisierung access-Methoden im data access layer.
Habe ich wirklich gesehen, 2 unterschiedliche Umsetzung, und es gibt keine formale Beispiele online, die, die ich gesehen habe, sind versteckt in den Büchern.
Umsetzung 1 :
public Interface IRepository<T>{
List<T> GetAll();
void Create(T p);
void Update(T p);
}
public interface IProductRepository: IRepository<Product> {
//Extension methods if needed
List<Product> GetProductsByCustomerID();
}
Umsetzung 2 :
public interface IProductRepository {
List<Product> GetAllProducts();
void CreateProduct(Product p);
void UpdateProduct(Product p);
List<Product> GetProductsByCustomerID();
}
Bemerken, die erste ist generischer Get/Update/GetAll, etc, die zweite ist mehr von dem, was ich definieren würde "DAO" wie.
Beide teilen sich eine Extraktion aus den Daten der Entitäten. Die ich mag, aber ich kann das gleiche tun mit einem einfachen DAO. Aber das zweite Stück der Zugang zu standardisieren Operationen, die ich sehen Wert, wenn Sie implementieren diese unternehmensweite würden die Leute einfach wissen, der Satz von Zugriffsmethoden für das repository.
Bin ich falsch anzunehmen, dass die Standardisierung der Zugriff auf Daten ist ein integraler Bestandteil dieses Muster ? Wenn beide richtig sind, warum soll man auswählen und Implementierung 2?
Rhino hat einen guten Artikel über die Umsetzung von 1, und natürlich MS hat eine vage definition und ein Beispiel für die Umsetzung 2 ist hier.
- Mir ein interface ist eine Abstraktion, also das Gegenteil von einer Umsetzung. Besprechen wir nur die Schnittstellen hier, oder vielmehr die Implementierung von Klassen?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich die zweite Fowler Zitat zitiert von oded. Ich möchte darauf hinweisen, dass er sagte: "Sammlung-wie" - Schnittstelle. Wie Sie implementieren das collection interface ist sicherlich bis zu Ihnen, aber weder kann noch sollte Sie versuchen sich zu verstecken die Tatsache, es stellt eine remote-Datenquelle. Es unterscheidet sich deshalb deutlich von einer in-memory-Sammlung, die braucht nicht Spülen, um änderungen an einem remote-Daten zu speichern. Die change tracking-Mechanismus Ihres ORM oder Ihr roll-your-own-Lösung bestimmt, wie transparent dies kann gemacht werden, um den Anrufer. Löscht in der Regel müssen explizit markiert werden, Einfügungen sind erkennbar (Persistenz durch Erreichbarkeit) und updates manchmal müssen gekennzeichnet werden ausdrücklich zu. Kombinieren Sie dies mit der komplizierten Abhängigkeiten der gesamtwirtschaftlichen Wurzeln und du wirst sehen, dass das nicht gerade eine Sammlung wie.
Gibt es keine solche Sache wie "die cannonical repository-Implementierung".
Es ist ein ständiger Kampf zwischen den Befürworter eines generischen repository-base-Klasse und diejenigen, die lieber ein Umsetzung jedes repository auf seinem eigenen. Während die generische Implementierung ist Ansprechend in einfachen Szenarien, wird man sehr oft feststellen, dass es eine sehr undichte Abstraktion. Zum Beispiel einige Ihrer Aggregate dürfen nur soft gelöscht (cistomizable über virtuelle Methode überschreibt), während andere keine Unterstützung für eine delete-operation überhaupt.
Stellen Sie sicher, Sie verstehen die Implikationen des jeweiligen Ansatzes vor der Entscheidung, welche route zu nehmen. Greg Young hat einen guten Beitrag über die Vorzüge des generischen repositories.
http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx
Von Martin Fowler "Patterns of Enterprise Application Architecture", die definition des Repository-Musters ist:
So, beide Ansätze sind richtig.
Ich bin ein großer fan des generischen repository-Muster, aber ich denke, Sie sollten ernsthaft in Betracht ziehen, die nicht direkt Erben von der Schnittstelle kann es eine sehr große Einschränkung, vor allem, da viele mal den code für die generische Schnittstelle werden die gleichen sein, dass es sein könnte, definiert eine abstrakte Basisklasse, die Sie nicht mehr in der Lage, mehr als 1 generic repository in einer Klasse.
Empfehle ich, dass Ihr IProductRepository Durchführung den Zugriff auf die generische
IRepository<Product>
durch delegation und Spritzen, dass in der durch den Konstruktor so können Sie Komponieren Sie Ihre Klasse möglichst viele IRepositories und gruppieren Sie Sie hinter einer einzigen Schnittstelle in einer Weise, die Sinn macht.Schrieb ich einen blog zu diesem Thema, während es speziell Verweise NHibernate dieses Muster angewendet werden können, um jede Art von repository: Die Schaffung eines gemeinsamen, generischen und erweiterbaren NHiberate Repository version 2
Mit der Einführung von LINQ in .NET, a generic repository pattern ist viel einfacher zu realisieren:
Qualifiziert als ein repository, muss Sie lediglich in der Lage sein, um den Zugriff auf Daten in der zugrunde liegenden Speicher (leicht bereitgestellt durch
IQueryable
), und ändern Sie die darin enthaltenen Daten.Können Sie Erweiterungen für das Basis-interface zu bieten Haken für weitere Entität-spezifische Verhaltensweisen (wie Verdrahtung in einem Aufruf einer gespeicherten Prozedur für eine SQL-basierten repository), aber die Mehrheit der Betriebe kann ergänzt werden durch die einfache Benutzeroberfläche.
Zusätzlich zu Ihrem generischen repository-Schnittstelle (Ausführung 1) und Ihre variation auf die Rolle-bestimmten-repository (Implementierung 2) Sie können auch prüfen, eine generische Methode repository:
Diese Dritte version stammt von dieser Beitrag von Jimmy Bogard, wo er auch drückt die Vorliebe für das generische repository-Schnittstelle.
Ich in der Regel Folgen, dass mit einem generischen repository baseclass, die diese Schnittstelle implementiert; so, ich habe nur zu implementieren, die Sachen, die Verschieden für jede Domäne Entität.
Normalerweise verwende ich das generische repository mit der Komposition statt Vererbung. Das gibt mir den Vorteil einer generischen Implementierung, mit der Kontrolle, welche Methoden verfügbar zu machen.
Etwas wie dieses:
Dem repository-Muster ist eines der am meisten verwendeten Muster in der software-Entwicklung. Die viele post, die markiert werden können, als Antwort auf Ihre Frage.
Etwas, das ich gerne hervorheben, ist die Tatsache, dass eine gute repository-Implementierung wird verbessert, wenn Sie verwenden IoC (Autofac, Windsor, etc...). Ich Spiele seit langer Zeit mit einigen ADO.NET basierten frameworks (LinqToSql, EF) und NHibernate. Sie können immer die Vorteile aus einer generischen Implementierung, wenn Sie verwenden IoC.
Sie können die Definition von Schnittstellen für Ihre spezifischen repositories und lösen, wenn Sie wirklich brauchen einige Besondere Aktionen.