Wie zu verwenden Repository-Schnittstelle, nutzt Generics mit Dependency Injection?
Ich bin versucht, verwenden Sie die folgende Generische Repository-Schnittstelle für DI-und constructor injection:
public interface IRepository<TEntity> : IDisposable where TEntity : class
Das problem ist, um zu definieren, die eine Instanz der Schnittstelle, ich muss die Klasse geben, wie diese:
private IRepository<Person> _personRepository;
Das Problem mit diesem ist, wenn ich mit DI (und ich bin mit der Einheit für IoC-framework), dann muss ich definieren, mehrere Instanzen in meinem Konstruktor, um alle repository-Schnittstellen, die ich brauche, um mit zu arbeiten, wie diese:
public MyClass(IRepository<Person> personRepository,
IRepository<Orders> ordersRepository,
IRepository<Items> itemsRepository,
IRepository<Locations> locationsRepository)
{
_personRepository = personRepository;
_OrdersRepository = ordersRepository;
_itemsRepository = itemsRepository;
_locationsRepository = locationsRepository;
}
Fragen:
- Ist das OK?
- Wenn nicht, wo bin ich verloren auf diesem Konzept?
- Auch wenn das ist die richtige, was ist der Punkt der Einheit zu registrieren, Schnittstelle zu den konkreten Typ? Ich habe es schon getan, da die generische repository mich gezwungen auf Erklärung.
Hilfe bitte deaktivieren Sie dieses, für mich, und ich Schätze Ihre Hilfe!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sicher. Es ist persönliche Präferenz, ob constructor injection wie Sie haben oder property-injection. Constructor injection ist sauberer, da Sie nicht haben, um sehr viele Parameter an den Konstruktor, aber es ist sicherer als gut.
Ein Grund dafür ist, so dass Sie können unit-test
MyClass
ohne Ihre eigentliche repository schlägt in eine Datenbank. Sie können "fake", das repository zurück hartcodierte Werte zum testen gegen.IRepository<T> repository
als parameter der Methode, aber ich weiß, dass wird nicht funktionieren. Können Sie erklären, warum es nicht? Es fühlt sich falsch an indem alle von denen, aber vielleicht ist es die richtige und ich bin über-denken.Wie bereits von D Stanley, eine Abhängigkeit muss eine konkrete Schnittstelle. Ansonsten, wo sind Sie zu deklarieren, T? Ihre abhängig-Klasse können generisch sein, aber Sie haben noch zu sagen, dass "T ist eine Person, die" an einem gewissen Punkt.
Sagte, dass, Einheit verarbeitet Registrierung von generischen Typen ziemlich gut.
Lassen Sie uns sagen, Sie umzusetzen
IRepository<T>
mit einer generischen KlasseRepository<T>
umschließt, die eineDbSet<T>
(oder was auch immer).Folgende Anmeldung aus und löst dann die Arbeit (die Injektion in jeglicher Konstruktoren):
Wenn Sie benötigt eine spezifische überschreibung der eine Typ (sagt der Elemente repository ist speziell für welchem Grund auch immer, so hat es eine voll umgesetzt
ItemRepository
Klasse), nur registrieren, dass die konkrete Umsetzung nach dem generischen:Lösung
IRespository<Item>
erhalten nun Ihre konkrete Umsetzung.Für das Protokoll, ich denke, das kann nur sein getan in den code und nicht die Konfigurationsdateien. Jemand korrigiere diese Annahme.
<register type="IRepository[[Item]]" mapTo="ItemRepository" />
ist ein Beispiel. Liebe mich einige Einheit.Könnten Sie erwägen, einen Aggregate-Service, dass bundles verschiedenen anderen Diensten zusammen, aber man sollte auch genau hinschauen, um zu sehen, ob Ihr
MyClass
ist versuchen, zu viel zu tun; eine große Anzahl von Abhängigkeiten kann ein Indiz.Scheint dies ok außer einem fehlenden Punkt; Sie müssen UnitOfWork-pattern zu aktivieren Transaktionen.
Ohne UnitOfWork-pattern angewendet wird, werden alle repositories versuchen, commit db-Operationen auf verschiedene Kontexte.
Ich musste das tun, über die Konfigurationsdatei. Es ist eigentlich ziemlich einfach, aber ich brauchte eine Weile, um es herauszufinden.
In diesem Beispiel haben wir eine Schnittstelle
IRepository<T>
und es hat 2 Implementierungen:OneRepository
TwoRepository
Wir haben dann eine Klasse mit dem Namen
Worker
abhängigIRepository<One>
undIRepository<Two>
. Wir bitten die Einheit zum erstellen einer Instanz desWorker
für uns und herauszufinden, die Abhängigkeiten aus der config-Datei.Schnittstelle und Implementierung
Alle diese sind im namespace
ConsoleApplication1
in diesem Beispiel.Einheit Konfiguration
Bitte beachten: wir weisen der Einheit und sagen Sie den Namen der assembly. Dann registrieren wir die 2 Implementierungen.
Anwendung
Dies ist die Zusammensetzung Root.
Als Ausgabe zu erwarten ist: