Laden...

Dependency Injection vs Service Locater

Erstellt von Golo Roden vor 18 Jahren Letzter Beitrag vor 18 Jahren 1.833 Views
Golo Roden Themenstarter:in
4.207 Beiträge seit 2003
vor 18 Jahren
Dependency Injection vs Service Locater

Guten Morgen,

ich versuche derzeit, die beiden Design Patterns Dependency Injection und Service Locator zu verstehen.

Service Locator habe ich nun so aufgefasst, dass meine Anwendung explizit eine Anfrage an einen Locator stellt, gib mir eine Instanz der Art XYZ, der Locator schaut nach, welche Klasse er für XYZ zu verwenden hat, erzegt eine Instanz und gibt mir diese zurück.

Ist das richtig?

Dependency Injection .... hm, da habe ich schon mehr Probleme. Auf irgendeine Art und Weise (welche?) wird hier "von außen" die korrekte Instanz eingefügt. Aber wie? Und woher weiß wer eigentlich, was die korrekte Instanz ist? Letztlich muss ich das doch auch irgendwo konfigurieren, wo liegt dann noch der große Unterschied zum Service Locator?

Viele Grüße,

Golo

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

_
416 Beiträge seit 2005
vor 18 Jahren

Hallo,

Der Unterschied liegt wie bei den meisten Entwurfsmustern im Detail. ich denke den Service Locator benutzt man wenn es verschiedene Arten von Aufgaben gibt, aber die Services nicht von der Komponente bereitgestellt werden. D.h. die Komponente weiß genau was sie tun will, aber nicht wie sie es tun kann. Daher fragt sie nach einem Service und übergibt ihm die Aufgabe.

Bei Dependency-Injection ist es eher andersherum. Es gibt eine Aufgabe die auf verschiedene Arten erledigt werden kann. Die Komponete arbeitet aber so als würde es genau eine Implementierung geben.

Die Implementierung beider Muster kann sicher recht ähnlich sein. Der größte Unterschied ist imo, dass mit dem ServiceLocator Pattern zu unterschiedlichen Zeiten, unterschiedliche Services zurückgegeben werden können. Bspw.
EmailService GetEmailService(string Account)

Bei Dependency Injection arbeitet die Komponente immer mit dem selben Code, nämlich diesem der ihr zu allererst injiziert wurde und ist damit nicht ganz so dynamisch. Außerdem erwartet die Komponente meist die Einhaltung eines Vertrags. D.h. ob ein Emailservice statt einer Email eine SMS verschickt ist im Endeffekt egal. Abber wenn ein injiziertes Codestück nicht wie erwartet arbeitet kann dies zu unerwarteten Ergebnissen führen. (Bspw. ein Sortieralgorithmus der plötzlich abwärts sortiert)

cu, tb

Golo Roden Themenstarter:in
4.207 Beiträge seit 2003
vor 18 Jahren

Hallo,

zunächst einmal danke für Deine Antwort. Leider werde ich daraus noch nicht wirklich schlau. Du schreibst, den Service Locator würdest Du dann einsetzen, wenn die Komponente weiß, was sie tun will, aber nicht wie. Als Beispiel fällt mir dazu das Schreiben eines Logeintrages ein, die Komponente will ihn einfach nur schreiben, ob das nun aber in eine Datei oder in eine Datenbank geschieht, ist ihr schnuppe. Daher fragt sie nach einer konkreten Instanz von ILogWriter und schreibt gegen das Interface.

Bei der Dependency Injection schreibst Du nun sei es genau andersherum. Eine Augabe, die auf viele Arten erledigt werden kann. Mit meinem Beispiel habe ich hier aber genau die gleiche Situation: Das Schreiben eines Logeintrages, der eben in eine Datei oder eine Datenbank geschrieben werden kann.

Mir ist anscheinend noch nicht klar, wie Du das jeweils genau gemeint hast. Kannst Du mir vielleicht an Hand meines Beispieles zeigen, wo mein Denkfehler liegt?

Was ich nachvollziehen kann, ist, dass der Service Locator bei mehrmaligem Aufruf unterschiedliche Resultate liefern kann, weil er beispielsweise zur Laufzeit umkonfiguriert wird. Die Dependency Injection injiziert ein Mal das entsprechende Objekt und dann ist es eben da.

Du sprichst weiter an, dass bei Dependency Injection die Komponente meist die Einhaltung eines Vertrages erwarten würde. Dabei stimme ich Dir zu, aber ich frage mich, wieso das beim Service Locator nicht so sein sollte? Auch hier müssen doch die (austauschbaren) Services den gleichen Vertrag erfüllen, oder nicht?

Viele Grüße,

Golo

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

Golo Roden Themenstarter:in
4.207 Beiträge seit 2003
vor 18 Jahren

Hallo,

so, ich habe durch viel viel Lesen nun allmählich kapiert, wo der Unterschied liegt - meine zusammengefassten Gedanken finden sich unter http://www.des-eisbaeren-blog.de/Default.aspx?Guid=0ee55f4b-9bcc-46fd-bfdd-bfa172e1aede.

Viele Grüße,

Golo

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

_
416 Beiträge seit 2005
vor 18 Jahren

Hallo,

jap, so hatte ich das auch gemeint.

Mir ist nun auch noch ein schönes Beispiel für einen ServiceLocator im Framework eingefallen. Die Klasse WebRequest. Diese hat eine Factory-Methode Create welche eine URI übergeben bekommt. Anhand des Protokolls wird dann z.B. ein HttpWebRequest erzeugt. Man kann aber auch eigene Prefixe also Protokolle definieren und mit der ebenfalls statischen Methode RegisterPrefix publizieren. Danach werden dann URI mit bspw: "abc://blabla" an eine eigene Klasse weitergeleitet.

Also es ist schon so wie du geschrieben hast. Ein ServiceLocator ist flexibler. Nur man verwendet im Normalfall ja nie die flexibelste Lösung da die auch gleich die komplizierteste ist. Dependecy Injection ist im Zweifelsfall auch performanter, da nicht dauernd neu nachgefragt werden muss.

cu, tb

S
8.746 Beiträge seit 2005
vor 18 Jahren

Wie der Name schon sagt, sorgt Dependency Injection dafür, dass die Abhängigkeiten zwischen den Komponenten von "außen" in die Applikation eingebracht werden. Ein entsprechendes Framework (hier fällt immer der Begriff Microkernel) übernimmt bei Start die Kontrolle und erstellt anhand von Konfigurationsfiles die Beziehungen.

Anstelle also den Komponenten diese Aufgabe zu übertragen, sich selbst konfigurierbar zu machen, wird das komplett von außen gesteuert.

Die einzelnen Komponenten haben keinerlei feste Beziehung zu anderen Komponenten. Diese werden allesamt zur Laufzeit hergestellt. Der Ergebnis ist ein System in welchem ausschließlich über Interfaces kommuniziert wird.

Im Prinzip handelt es sich dabei um ein System mit maximaler Entkopplung.

Ein ServiceLocator sorgt auch für eine dynamische Konfiguration, aber er bezeichnet nur die Komponente, die Dienste zur Laufzeit auffindet. Im Rahmen von DI wäre so ein ServiceLocator Teil des Microkernel Frameworks.