Guice mit zirkulären Abhängigkeiten verwenden

8

Betrachten Sie dieses einfache Beispiel.

%Vor%

In diesem Beispiel kennt A Instanz B und Instanz B Instanz A.

Meine Frage ist: wie Instanz A mit Guice instantiiert wird, d. h. wie Guice sich um diese komplexen Kreisabhängigkeiten kümmert?

    
Yury Litvinov 26.09.2009, 18:15
quelle

4 Antworten

4

Um Ihre erste Frage zu beantworten, wie man Instanz A mit Guice instanziiert: Sie können einfach @Inject zum Konstruktor hinzufügen:

%Vor%

Dies funktioniert, weil die API zum Erstellen von A keine zirkuläre Abhängigkeit hat. Guice verwendet den Konstruktor A immer dann, wenn er ein Objekt A erstellen oder einfügen muss.

Wenn Ihre Frage lautet, wie Guice zum Erstellen eines Objekts verwendet wird, bei dem die API zum Erstellen des Objekts eine Kreisabhängigkeit aufweist, finden Sie unter diesen Blog-Eintrag von Misko Hevery (wie in Yury's Antwort erwähnt).

    
NamshubWriter 27.09.2009, 22:27
quelle
8

Ihr Beispiel ist überhaupt kein Problem, da Sie B direkt konstruieren. Aber wenn Sie möchten, dass sowohl A als auch B von Guice erstellt werden, sollte eine oder beide eine Schnittstelle sein. Sie können tun:

%Vor%

Auch wenn AImpl und BImpl als Singletons definiert sind, kann Guice diese Injektion (über einen Proxy) verarbeiten. Das funktioniert jedenfalls in einem einfachen Fall ... Ich könnte mir vorstellen, dass es komplexere zirkuläre Abhängigkeiten geben könnte, mit denen es nicht umgehen könnte. Jedenfalls wäre es natürlich vorzuziehen, zirkuläre Abhängigkeiten zu eliminieren.

    
ColinD 22.10.2009 20:51
quelle
4

Die Antwort ist, dass Sie kein Abhängigkeits-Injection-Framework verwenden sollten, während Sie in Ihrem Code zirkuläre Abhängigkeiten haben .

Sie müssen Ihren Code also vorher umgestalten. Soweit ich weiß, gibt es zwei Lösungen für eng gekoppelte Klassen: Entweder verschmelzen Sie zwei Klassen zu einer oder führen Sie eine neue Klasse ein und verschieben Sie die allgemeine Logik in diese (für Details siehe hier )

    
Yury Litvinov 27.09.2009 07:21
quelle
3

Ich denke, dass der Vorschlag von NamshubWriter nicht sehr zielführend ist. Ich denke, dass in Guice ein Konstruktor genau eines tun sollte: Parameter in Felder zuweisen. Wenn Sie noch etwas anderes tun müssen, legen Sie es in eine Fabrik oder einen Anbieter.

In diesem Fall wollen wir einen Provider für A. Der Provider könnte direkt B () anrufen, aber dann würden wir direkt A mit B verbinden, was wir in erster Linie vermeiden wollten. Also indirekt die Schaffung von B über eine Fabrik, die guice uns über assistedInject zur Verfügung stellen kann. Dieser Code wird ausgeführt und kompiliert und trennt A und B vollständig.

In einem realistischen Szenario müssten Sie A und B hinter Schnittstellen verstecken, um die Trennung zu nutzen.

%Vor%

Ich habe eine erweiterte Version der zirkulären Abhängigkeitsinjektion in Guice gemacht, wo A und B sind hinter Schnittstellen verborgen.

    
nes1983 25.05.2010 21:17
quelle

Tags und Links