2016-04-18 13 views
2

Ich habe ein Projekt, das eine Schnittstelle bietet, nennen wir es IImplementMe, die ich in mein Projekt injizieren möchte. Diese Schnittstelle wird von verschiedenen Herstellern implementiert, so dass ich alle Implementierungen injizieren muss. Ich versuche TypeLiteral dafür zu verwenden.Java injizieren Implementierung mit TypeLiteral

Hier ist der Code des Herstellers ist:

@Singleton 
public class SomeImplementation implements IImplementMe { 

private final String value; 

@Inject 
public SomeImplementation(final SomeOtherConfig configuration) { 
    this.value= configuration.getValue(); 
} 

@Override 
public String getValue() { 
    return value; 
} 
} 

Und in meinem Registrierungs Klasse habe ich register(IImplementMe.class).to(SomeImplementation.class);

Dann habe ich in meinem Projekt injizieren es wie folgt aus:

@Inject 
public SomeEndpoint(final List<IImplementMe> implementations){ 
/// 
} 

und Ich binde es wie

private static class MarketDataSetTypeLiteral extends TypeLiteral<List<IImplementMe>> { 
} 
bind(new MarketDataSetTypeLiteral()).toRegistry(); 

Ich habe sichergestellt, dass mein SomeIMplementation-Konstruktor aufgerufen wird, aber an meinem Endpunkt ist die Liste leer, so dass keine Implementierung bereitgestellt wird. Ich verwende Guice für die Injektion. Irgendwelche Ideen ?

LE: Es stellt sich heraus, dass die bereitgestellte Implementierung erstellt wird, nachdem meine Endpunktklasse erstellt wurde (zur Erstellungszeit injiziert sie eine Referenz einer leeren Liste). Später im Lebenszyklus wird die Referenz mit der Implementierung aktualisiert, so dass ich tatsächlich Zugriff darauf habe, nachdem es richtig funktioniert.

Ich vermute, dass es wegen der Maven-Abhängigkeiten ist, und wie guice die Instanziierungen behandelt. Da der Produzent eine Abhängigkeit von meinem Projekt haben muss, ist es wahrscheinlich sinnvoll, dass es zuletzt instanziiert wird, was mein anfängliches Problem verursacht.

+0

Ich bin mir nicht sicher, ob ich verstehe, warum Sie ein 'CustomTypeLiteral' (meinten Sie' MarketDataSetTypeLiteral'?) Oder was Sie mit 'toRegistry' machen wollen. Im Allgemeinen sieht es so aus, als würden Sie eine ähnliche Funktion wie [Multibindings] (https://github.com/google/guice/wiki/Multibindings), jedoch mit Ihrer eigenen Registrierung, ausführen. Können Sie uns mehr zeigen, was 'bind (...). ToRegistry()' tun sollte oder wie Sie es implementiert haben? –

+0

Ja, tut mir leid, es sollte MarketDataSetTypeLiteral sein. Und für die Registry-Implementierung ist es im Grunde die Yar Registry-Implementierung (Link: https://github.com/javabits/yar/blob/master/yar-guice/src/main/java/org/javabits/yar/guice/RegistryAnnotatedBindingBuilderImpl .Java). –

Antwort

0

Sie suchen multibindings ->https://github.com/google/guice/wiki/Multibindings

public class IImplementMeModule extends AbstractModule { 
    public void configure() { 
    Multibinder<IImplementMe> uriBinder = Multibinder.newSetBinder(binder(), IImplementMe.class); 
    uriBinder.addBinding().to(SomeImplementationOfIImplementMe.class); 
    uriBinder.addBinding().to(AnotherImplementationOfIImplementMe.class); 

    ... // bind plugin dependencies, such as our Flickr API key 
    } 
} 

Dann können Sie den Satz von IImplemetnMe injizieren, wie folgend

@Inject TweetPrettifier(Set<IImplemetnMe> implementations) 

Ich würde Ihnen vorschlagen, einen Blick auf MapBindings zu haben, die erlaubt Sie geben Schlüssel für jede Implementierung und dann können Sie Ihre Bindungen als Karte

injizieren
+1

Danke Milan, das scheint eine gute Alternative zu sein, schau mal :) –