Guice: Injector übergeben?

Jay_030

Aktives Mitglied
Hi,

bin gerade dabei mich in Guice einzuarbeiten. Und bisher fand ich das alles sehr schick und einleuchtend. Aber jetzt bin ich an einem Punkt, wo ich mal einen guten Ratschlag von euch brauche.

Ich habe eine Klasse A, die in einer Methode Objekte der Klasse B erzeugt. Dafür bekommt die Klasse A im Konstruktur eine Factory für Klasse B injiziert. Diese Factory hat eine newInstance()-Methode mit Rückgabetyp der Klasse B. Um jetzt neue Objekte der Klasse B erzeugen zu können, die auch mit Konstruktor-Injection arbeitet, müsste ich blöderweise den Injector von Guice mit übergeben, um dann
Java:
injector.getInstance(KlasseB.class);
aufrufen zu können... aber das kann ja nicht die Lösung sein, oder etwa doch?

Klasse A und B implementieren jeweils Interface A bzw. B. Auch die Factory implementiert das Interface Factory für Klasse B. Ich hatte eigentlich gehofft, mein Problem mit der Factory zu lösen. Aber dadurch habe ich es nur in die Factory verschoben.

Was ich mir noch vorstellen könnte, in Klasse B mit Setter Injection zu arbeiten. Dann müsste Guice mit Auto Binding arbeiten. Was aber auch wieder nicht geht, da ich das Interface B schlecht instanzieren kann. ???:L

Ich bin verwirrt. Vielleicht ist es auch nur zu spät und ich sehe morgen klarer. :gaen:
 

Landei

Top Contributor
Ich denke Wildcard hat Recht.

Ich benutze AssistedInjection an einer Stelle: Eigentlich will ich mein Hauptfenster injizieren lassen, es muss aber einen Nutzernamen übergeben bekommen. Deshalb injiziere ich stattdessen eine Factory:
Java:
public class MyApp {
   @Inject
    private MyApp(MainFrameFactory mainFrameFactory) {
        String userName = loginAndAuthenticate();
        MainFrame mainFrame = mainFrameFactory.create(userName);
    }

    public static void main(String[] args) {
        final Injector injector = Guice.createInjector(new SomeModule());
        injector.getInstance(MyApp.class);
    }
}

Die Factory muss ich nicht implementieren, ein Interface reicht, den Rest bastelt Guice:
Java:
public interface MainFrameFactory {
   MainFrame create(String userName);
}

Das MainFrame wird mit dem "assistiert" übergebenen Nutzernamen und ganz normal injizierten Parametern konstruiert:
Java:
public class MainFrame {
    @Inject
    public MainFrame(@Assisted String userName,
            UserManager userManager,
            Set<WorktimePanel> panels) {
    }
    ...
}

Die Bindung im Modul sieht so aus:
Java:
public class SomeModule {
     protected void configure() {
        bind(MainFrameFactory.class).toProvider(
                FactoryProvider.newFactory(MainFrameFactory.class, MainFrame.class));
         //und die anderen Sachen, die MainFrame braucht
     }
}

Hoffe das hilft.
 

Jay_030

Aktives Mitglied
Danke euch beiden. AssistedInjection hat mein Problem gelöst. Hatte die FAQ-Seite dazu gestern sogar schon aufgehabt, aber sie nur überflogen. :D

Ein wenig merkwürdig kommt mir die Lösung aber dennoch vor, da ich dadurch an einer Stelle eine Factory in einer Factory habe, bedingt durch das automatische Erzeugen der ProviderFactory von Guice. Wäre gut nochmal zu hören, was ihr davon haltet (CellGridFactory und CellGridProviderFactory).

Damit das nicht zu trocken wird, poste ich den Code dazu.

Es handelt sich um eine GameOfLife-Implementierung. Mein persönliches HelloWorld, um mit neuen Frameworks vertrauter zu werden. Das Problem ist mir gestern bei folgender Methode aufgefallen:
Java:
public class GameOfLifeImpl implements GameOfLife {
    ...
    @Override
	public void next() {
		CellGrid nextGeneration = cellGridFactory.newInstance(cellGrid);
		computeNextGenerationCellGrid(nextGeneration);
		setCellGrid(nextGeneration);
		incrementGeneration();
	}
    ...
}
Die Factory musste anhand des übergebenen CellGrids (also dessen Breite, Höhe etc pp) eine neue CellGrid-Instanz erzeugen. Des Weiteren bietet diese Factory noch Methoden, um CellGrids zu erstellen, die zufällig mit Zellen befüllt sind.
Java:
public interface CellGridFactory {

    CellGrid newInstance(CellGrid cellGrid);
    CellGrid newInstance(int width, int height, boolean isTorus);

    CellGrid newInstanceFilledRandomlyWithCells(CellGrid cellGrid);
    CellGrid newInstanceFilledRandomlyWithCells(int width, int height, boolean isTorus);
}
Ich habe das Problem jetzt wie folgt gelöst: Die Klasse CellGridImpl hat drei AssistedInject-Parameter im Konstruktor (width, height, isTorus). Dabei mussten width und height als NamedAssisted annotiert werden, da sie den gleichen Typ haben und Guice ohne die Namen keine Zuweisung machen kann. Dann gibt es eine "DummyFactory", die ich CellGridProviderFactory genannt habe. Das ist die von Guice automatisch erzeugte Factory. Diese wird der eigentlichen CellGridFactory im Konstruktor injiziert. Es ist halt nur schade, dass Guice bei der erzeugten Factory lediglich diese create-Methode zulässt und man nicht selbst noch eigene Factory-Methoden implementieren kann. Deswegen dieser kleine Umweg über die CellGridFactory mit injizierter CellGridProviderFactory.

Natürlich könnte man argumentieren, dass das zufällige Befüllen mit Zellen, in die Klasse CellGridImpl verschoben werden könnte oder in eine Helper-Klasse als statische Methode. Aber dieses Projekt ist ein bereits implementiertes und ich wollte versuchen, die Struktur möglichst beizubehalten - mit Guice nur die Bindings vornehmen. Außerdem finde ich, passt das zufällige Befüllen mit Zellen sehr gut in eine Factory und man erspart sich unnötige statische Helfermethoden.

CellGridImpl mit benannten Assisted-Parameter:
Java:
public class CellGridImpl implements CellGrid {

    private int width;
    private int height;
    private boolean isTorus;

    ...

    @Inject
    public CellGridImpl(@Assisted("width") int width, @Assisted("height") int height,
            @Assisted boolean isTorus) {
        checkArgument(width > 0, "width must be greater than 0");
        checkArgument(height > 0, "height must be greater than 0");

        this.width = width;
        this.height = height;
        this.isTorus = isTorus;
        ...
    }

    ...
}

Die eigentliche CellGridFactory-Implementierung:
Java:
public class CellGridFactoryImpl implements CellGridFactory {

    private CellGridProviderFactory cellGridProviderFactory;

    @Inject
    public CellGridFactoryImpl(CellGridProviderFactory cellGridProviderFactory) {
        checkNotNull(cellGridProviderFactory);
        this.cellGridProviderFactory = cellGridProviderFactory;
    }

    ...

    @Override
    public CellGrid newInstance(int width, int height, boolean isTorus) {
        checkArgument(width > 0, "width must be greater than 0");
        checkArgument(height > 0, "height must be greater than 0");
        return cellGridProviderFactory.create(width, height, isTorus);
    }

    ...

    @Override
    public CellGrid newInstanceFilledRandomlyWithCells(int width, int height,
            boolean isTorus) {
        CellGrid newCellGrid = newInstance(width, height, isTorus);
        fillRandomlyWithCells(newCellGrid);
        return newCellGrid;
    }

    ...
}

Das Interface für die DummyFactory, welches Guice benötigt, um mit den Assisted-Annotations arbeiten zu können (Wichtig: Auch hier muss man mit den gleichen benannten Assisted Parametern arbeiten wie bei CellGridImpl):
Java:
public interface CellGridProviderFactory {

    CellGrid create(@Assisted("width") int width, @Assisted("height") int height, boolean isTorus);
}

Der provisorische Startpunkt, um zu testen, ob Guice die Konfiguration schluckt:
Java:
public class JLifeMain {

    public static void main(String[] args) {
        Injector injector = Guice.createInjector(createMainModule());

        GameOfLifeProviderFactory gameOfLifeProviderFactory = injector.getInstance(GameOfLifeProviderFactory.class);
        CellGridFactory cellGridFactory = injector.getInstance(CellGridFactory.class);

        CellGrid cellGrid = cellGridFactory.newInstance(100, 100, true);
        GameOfLife gameOfLife = gameOfLifeProviderFactory.create(cellGrid);
        gameOfLife.next();
    }

    private static AbstractModule createMainModule() {
        return new AbstractModule() {

            @Override
            protected void configure() {
                bind(GameOfLifeProviderFactory.class).toProvider(
                        FactoryProvider.newFactory(GameOfLifeProviderFactory.class, GameOfLifeImpl.class));
                bind(CellGridProviderFactory.class).toProvider(
                        FactoryProvider.newFactory(CellGridProviderFactory.class, CellGridImpl.class));
                bind(CellGridFactory.class).to(CellGridFactoryImpl.class);
                bind(Neighborhood.class).to(NeighborhoodImpl.class);
                bind(Rule.class).to(RuleImpl.class);
            }
        };
    }
}
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Guice - Ohne injector.getInstance Allgemeine Java-Themen 2
L Compiler-Fehler Google Guice Module zur Laufzeit zusammenstellen und binden Allgemeine Java-Themen 4
L Guice Dependency Injection Allgemeine Java-Themen 0
L Google Guice Field Injection returns null Allgemeine Java-Themen 2
I WebSockets mit Jersey und Guice Allgemeine Java-Themen 0
T GUICE- Dependency Injection- WANN nutze ich Providers? Allgemeine Java-Themen 2
M Google Guice (Assisted Injects) - Buggy oder mach ich's falsch? Allgemeine Java-Themen 5
F Google Guice + Generics + Vererbung Allgemeine Java-Themen 5
F rekursiver Aufruf (Sudoku und Guice) Allgemeine Java-Themen 19
Landei Guice - Injection von "zwischendurch" erzeugten Objekten Allgemeine Java-Themen 4
F DI @SesionScoped Guice Allgemeine Java-Themen 4
Jay_030 Guice + Hibernate = Probleme? Allgemeine Java-Themen 2
Jay_030 Guice: Frage im Umgang mit Unit-Tests Allgemeine Java-Themen 4
DamienX Google Guice AOP + Logging Allgemeine Java-Themen 3
Maxi-JOO Klassen Dummy Objekt in anderen Constructor übergeben Allgemeine Java-Themen 5
N Value Wert aus HTML-Button mittels thymeleaf spring an java übergeben Allgemeine Java-Themen 2
O Arrays an DOCX-Stamper Library übergeben Allgemeine Java-Themen 1
L Die abzuleitende Klasse als Parameter übergeben Allgemeine Java-Themen 4
1 Klassen Variabel aus Schleife übergeben Allgemeine Java-Themen 8
T Wert an laufenden Java-Prozess übergeben Allgemeine Java-Themen 10
Neumi5694 Methoden Generic: Rückgabetyp als Class-Parameter übergeben Allgemeine Java-Themen 3
F Enum-werte als Methoden-Parameter übergeben Allgemeine Java-Themen 6
H Consumer (Java8 Lambda) an Timer übergeben Allgemeine Java-Themen 2
R Abstrakte Basisklasse und instanzierte Objekte der abgeleiteten Klasse als Basisklasse übergeben Allgemeine Java-Themen 2
P Prüfen ob es Variable mit Namen gibt der als String übergeben wird Allgemeine Java-Themen 7
T C DLL einbinden und Pointer übergeben Allgemeine Java-Themen 13
S Klassen übergeben Allgemeine Java-Themen 13
X Komponente an Methode übergeben Allgemeine Java-Themen 1
F JFrame übergeben Allgemeine Java-Themen 5
F Classpath als Argument in Funktion übergeben Allgemeine Java-Themen 3
D Arraylist eigener Klasse an iReport übergeben Allgemeine Java-Themen 7
I JFrame Icon in Main übergeben Allgemeine Java-Themen 1
V int Array einer return Methode übergeben? Allgemeine Java-Themen 4
D Vererbung Wie auf Subklasse zugreifen + übergeben? Allgemeine Java-Themen 5
F Variable übergeben?! Allgemeine Java-Themen 2
J Verbindungsdaten an Subklasse übergeben? Allgemeine Java-Themen 5
N Objekte an eine andere Applikation übergeben Allgemeine Java-Themen 3
L nach form submit textfeld an java übergeben? Allgemeine Java-Themen 2
Joew0815 JList + JTableModel: Parameter der Tabelle übergeben Allgemeine Java-Themen 10
M Probleme mit String in Label übergeben. Allgemeine Java-Themen 6
M JExcel Wert aus Zelle übergeben/ausgeben Allgemeine Java-Themen 2
M Arraynamen an andere Klasse übergeben für allg. Rechnung Allgemeine Java-Themen 7
C char und char-Array als parameter übergeben Allgemeine Java-Themen 6
C Reflektions, Benutzer soll Konstruktor auswählen und Parameter übergeben können Allgemeine Java-Themen 5
V StyledDocument mit Writer übergeben Allgemeine Java-Themen 8
S JDialog Daten ins JFrame übergeben Allgemeine Java-Themen 5
C Argument an einen Thread übergeben Allgemeine Java-Themen 4
L Apache CLI: Args[] übergeben Allgemeine Java-Themen 3
E Array im Konstruktor übergeben Allgemeine Java-Themen 3
GianaSisters ArrayList in Methoden übergeben Allgemeine Java-Themen 3
GianaSisters ArrayList übergeben funktioniert nicht Allgemeine Java-Themen 4
W ScriptEngine + Wie Parameter übergeben bei Fukntion? Allgemeine Java-Themen 2
N Datenstrukturen an neue Klasse übergeben Allgemeine Java-Themen 16
S String in eine andere Klasse übergeben Allgemeine Java-Themen 25
DStrohma String an URI übergeben der ? = & enthällt Allgemeine Java-Themen 13
B Daten an Tabel Model übergeben Allgemeine Java-Themen 8
A Array übergeben/abrufen Allgemeine Java-Themen 4
J Parameter an Java übergeben Allgemeine Java-Themen 10
H root-Passwort übergeben Allgemeine Java-Themen 28
A Variable Parameterinhalte an einen Query übergeben? Allgemeine Java-Themen 3
A wie kann man Parameter an ein Task übergeben? Allgemeine Java-Themen 3
M Variablen an Java-Programm übergeben Allgemeine Java-Themen 3
X Methode: ArrayList byRef übergeben Allgemeine Java-Themen 22
S Objekt übergeben ??? Allgemeine Java-Themen 4
J Collections in Instanzattributen als Kopie übergeben Allgemeine Java-Themen 4
T UserID übergeben Allgemeine Java-Themen 8
W Properties-Klasse: mehrere Parameter-Belegungen übergeben? Allgemeine Java-Themen 2
V Wie Enum an Funktion "übergeben" ? Allgemeine Java-Themen 4
0 Stream/Datei an VLC übergeben und abspielen Allgemeine Java-Themen 10
G Linked List zwischen zwei Threds übergeben Allgemeine Java-Themen 11
N Wie einem Thread ein Objekt übergeben Allgemeine Java-Themen 9
S .rar-Dateien ein Passwort als Parameter übergeben Allgemeine Java-Themen 5
B Referezen auf Objekte an Methoden übergeben Allgemeine Java-Themen 2
O Kommandozeilenparameter mit Eclipse übergeben Allgemeine Java-Themen 5
M variable übergeben NICHT KOPIEREN Allgemeine Java-Themen 12
M Parameter an main übergeben aber wie? Allgemeine Java-Themen 4
T Parameter an Thread übergeben Allgemeine Java-Themen 8
T Files an das Betriebsystem übergeben such ideen! Allgemeine Java-Themen 3
B Array von Vektoren by reference übergeben Allgemeine Java-Themen 5
E methodenname übergeben Allgemeine Java-Themen 8
M connection übergeben Allgemeine Java-Themen 20
B wird Vektor als Referenz übergeben? Allgemeine Java-Themen 5
J Interface als Parameter übergeben Allgemeine Java-Themen 4
R Eine Variable an eine Methode mit Array übergeben Allgemeine Java-Themen 7
C String korrekt übergeben Allgemeine Java-Themen 8
M richtiges Ergebnis zählen und übergeben? Allgemeine Java-Themen 7
E markierten text im windowsprogramm an javaprog. übergeben? Allgemeine Java-Themen 9
H JSF - Wert an ein managed bean übergeben Allgemeine Java-Themen 2
J Array an paint übergeben Allgemeine Java-Themen 6
F array als referenz/werteparameter übergeben? Allgemeine Java-Themen 2
N Wie parameter von java aus an anderes Programm übergeben? Allgemeine Java-Themen 7
B jar per doppelklick auf datei parameter übergeben Allgemeine Java-Themen 5
O String übergeben ist name eines JTextField wie zugreifen Allgemeine Java-Themen 9
S Daten in andere Klasse übergeben Allgemeine Java-Themen 5
M Datenbankinhalt an StringArray übergeben Allgemeine Java-Themen 8
S Klasse einer Methode übergeben und überprüfen Allgemeine Java-Themen 7
T Werte übergeben, aber Array erhalten? Allgemeine Java-Themen 7
E Einer Methode sich selbst übergeben . ? Allgemeine Java-Themen 5
P Post-Parameter übergeben Allgemeine Java-Themen 3
T statisches String Array an Methode übergeben Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben