2015-04-16 3 views
6

Angenommen, ich habe das folgende Muster oft in meinem Code zu wiederholen:Guice: Wie bind ich Generika für alle Typen?

class A<T> { 
    @Inject 
    public A(List<T> list) { 
     // code 
    } 
} 

I alleList<T>-ArrayList<T> binden möchten. Ich weiß, ich kann TypeLiteral s verwenden, um einen expliziten unformatierten Typ zu binden, z. B. List<String>, aber gibt es das sowieso, um dies für alle Typen zu tun?

Grundsätzlich sollte dieser Code nicht scheitern, weil ich ausdrücklich nicht Liste binden:

injector.getInstance(new Key<A<Integer>>(){}); 
+1

Nach dem, was ich gefunden und versucht, so weit. Es ist nicht möglich. –

+1

Eine Diskussion über diese Art von "Wildcard" -Bindung finden Sie hier: https://github.com/google/guice/issues/852 –

Antwort

3

Diese in Guice nicht möglich ist. Intern ist Guice wenig mehr als ein HashMap<Key, Provider<?>>, wobei Key eine optionale bindende Annotation und einen einzelnen vollständig qualifizierten Typ darstellt. Um einem "Muster" von Typen zu entsprechen, würde ein Schlüssel sich mehr wie ein Prädikat verhalten müssen, was eine sehr unterschiedliche Architektur erfordern würde und die Bindungssuche viel langsamer machen würde.

Außerdem, obwohl Sie List für ein einfaches Beispiel verwenden, denken Sie daran, dass Guice-Bindungen besser für äquivalente Implementierungen reserviert sind, die in Produktion oder Tests variieren können. Zusätzlich zu den sehr unterschiedlichen algorithmusspezifischen Leistungsmerkmalen unterscheiden sich List-Implementierungen in ihrer Fähigkeit, null Elemente zu behandeln, und wenn Sie erst einmal eine ideale Listenimplementierung für einen bestimmten Algorithmus ausgewählt haben, müssen Sie diese wahrscheinlich nicht ändern - insbesondere in einem Anwendungsweite Konfiguration.

Wenn Sie Ihre generische Implementierungen mit Guice-Stil Konfiguration zu variieren, erstellen Sie eine sehr kleine Fabrik wie ListFactory Sie wollen in der Lage sein:

public class ListFactory { 
    public <T> List<T> createFooBarList() { return new ArrayList<T>(); } 
    public <T> List<T> createSomeOtherList() { return new LinkedList<T>(); } 
}