Dependency injection mit mehreren repositories
Habe ich einen wcf-Dienst und auf dem client habe ich:
var service = new ServiceReference1.CACSServiceClient()
Den eigentlichen Dienst-code:
public CACSService() : this(new UserRepository(), new BusinessRepository()) { }
public CACSService(IUserRepository Repository, IBusinessRepository businessRepository)
{
_IRepository = Repository;
_IBusinessRepository = businessRepository;
}
So, all das funktioniert gut, aber ich weiß nicht, wie ich bin newing alle repositories zur gleichen Zeit, da der client-code nicht brauchen, um neue bis die UserRepository
- und nur daran interessiert, newing die BusinessRepository
. Also, gibt es eine Möglichkeit bestehen etwas zu diesem code:
var service = new ServiceReference1.CACSServiceClient()
sagen Sie das repository, um neue basiert auf dem code, der den Aufruf der service-oder sonstige Beratung, die ich brauche, um darüber zu gehen bei der Gestaltung des repositories für meine entity framework. Thankx
- +1 für "newing-up"
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die Schönheit der Reine DI ist, dass Sie sollte sich keine sorgen über die Lebensdauer Ihrer Abhängigkeiten, weil diese für Sie verwaltet, wer Sie erbringen (ein DI-Container, oder einen anderen code, den Sie selber geschrieben haben).
(Als eine Nebenbemerkung, Sie sollten loswerden Ihre aktuelle Bastard Injektion Konstruktoren. Werfen Sie den parameterlosen Konstruktor und halten Sie die eine, die explizit damit wirbt, seine Abhängigkeiten.)
Halten Sie den Konstruktor wie diese, und verwenden Sie _IRepository und _IBusinessRepository Bedarf:
Wenn Sie sich sorgen, dass eines dieser Repositorys nicht zur Laufzeit benötigt werden, können Sie sich Spritzen, ein lazy-loading Realisierung von, sagen wir, IUserRepsository anstelle des realen ein, die Sie ursprünglich im Sinn hatte.
Lassen Sie uns davon ausgehen, dass IUserRepository sieht wie folgt aus:
Setzen Sie ein lazy loading Implementierung wie diese:
Beim erstellen CACService, können Sie dies durch die Injektion LazyUserRepository in es, die dafür sorgt, dass die real UserRepository ist nur initialisiert, wenn Sie benötigt wird.
Die Schönheit dieses Ansatzes ist, dass Sie nicht haben, um dies zu tun, bis Sie es brauchen. Oft sind diese nicht wirklich notwendig sein, so ist es schön, in der Lage sein zu verschieben solche Optimierungen, bis Sie tatsächlich benötigt werden.
Ich zuerst beschrieben die Technik der Faul Abhängigkeiten hier und hier.
Anstelle der Instanziierung ("newing-up") des repositories auf dem Bau, Sie könnten faul, laden Sie Sie in Ihren Eigenschaften. Dies würde ermöglichen es Ihnen, halten Sie Ihre zweite Konstruktor, sondern haben Ihre erste Konstruktor nichts zu tun.
Könnte der Benutzer dann ordnen Sie diese, wie erforderlich, sonst.
Beispiel:
Tun Sie Ihre repositories object-level-Zustand? Wahrscheinlich nicht, so erstellen Sie Sie als singletons und haben einen DI-container zur Verfügung zu stellen CACService.
Ansonsten sind Sie tatsächlich teuer zu erstellen? Wenn nicht, erstellen Sie eine neue pro Anfrage hat vernachlässigbaren Kosten im Vergleich zu den RPC-und Datenbank-Operationen.
Mithilfe der Ninject dependency-injection-container, Ihre CACService könnte wie folgt Aussehen. Andere DI-Container haben ebenso prägnante Mechanismen, dies zu tun.
Und während Sie Ihre Anwendung starten, würden Sie sagen, Ninject über diese Typen.
Vorwort: Dies ist eine Allgemeine Anleitung zu dependency inversion. Wenn Sie die default-Konstruktor, um die Arbeit zu tun (z.B. wenn es neue ed durch Reflexion oder etwas anderes), dann werde es schwieriger sein, zu tun, diese sauber.
Wenn Sie möchten, um Ihre Anwendung konfigurierbar, es bedeutet, in der Lage zu unterscheiden, wie Sie Ihr Objekt-graph konstruiert wird. In wirklich einfachen Worten, wenn Sie variieren möchten, eine Umsetzung von etwas (z.B. manchmal möchte man eine Instanz von
UserRepository
, andere Zeiten, die Sie wollen, die eine Instanz vonMemoryUserRepository
), dann der Typ, der verwendet der Umsetzung (CACService
in diesem Fall) sollten nicht geladen werden, mit newing es. Jede Verwendung vonnew
bindet Sie an eine bestimmte Implementierung. Misko geschrieben hat, einige nette Artikel über diesen Punkt.Das dependency-inversion-Prinzip wird oft als "parametrieren von oben", als jeden konkreten Typ erhält seine (bereits instanziiert), Abhängigkeiten von dem Anrufer.
Dies in die Praxis umzusetzen, verschieben Sie das Objekt erstellen code aus der
CACService
's parameterlosen Konstruktor und legen Sie es in einer Fabrik, statt.Können Sie dann wählen, verdrahten Sie die Dinge anders, basierend auf Dingen wie:
Trennung von Typen in zwei Kategorien (Arten, die erstellen Dinge und Arten, die tun Dinge) ist eine leistungsfähige Technik.
E. g. hier ist eine relativ einfache Möglichkeit, es zu tun mit einem factory-interface -- wir einfach, bis ein neuer welches Werk eignet sich für unsere Bedürfnisse, und rufen Sie seine
Create
Methode. Wir verwenden ein Dependency-Injection-container (Autofac) zu tun, dieses Zeug bei der Arbeit, aber es kann overkill für Ihre Bedürfnisse.