Guice

2010-04-05 24 views
25

ile enjekte edilen jenerikler Bazı fabrikaları Guice ile değiştirerek küçük bir projeyi geçirmeye çalışıyorum (bu benim ilk Guice denememdir). Ancak, jenerik enjekte çalışırken takılıyorum. Ben bu örneği çalıştırdığınızdaGuice

import com.google.inject.Inject; 

public class Console<T> { 
    private final StringOutput<T> out; 
    @Inject 
    public Console(StringOutput<T> out) { 
    this.out = out; 
    } 
    public void print(T t) { 
    System.out.println(out.converter(t)); 
    } 
} 

public class StringOutput<T> { 
    public String converter(T t) { 
    return t.toString(); 
    } 
} 

import com.google.inject.AbstractModule; 
import com.google.inject.Guice; 
import com.google.inject.Injector; 
import com.google.inject.TypeLiteral; 


public class MyModule extends AbstractModule { 

    @Override 
    protected void configure() { 
    bind(StringOutput.class); 
    bind(Console.class); 
    } 

    public static void main(String[] args) { 
    Injector injector = Guice.createInjector(new MyModule()); 
    StringOutput<Integer> out = injector.getInstance(StringOutput.class); 
    System.out.println(out.converter(12)); 
    Console<Double> cons = injector.getInstance(Console.class); 
    cons.print(123.0); 
    } 

} 

, elimdeki tek geçerli:: İki sınıfları ve bir modül ile küçük oyuncak örneğini çıkarmak için yönetilen dizisindeki

"ana" com.google.inject.CreationException : Guice oluşturma hataları:

1) playground.StringOutput<T> cannot be used as a key; It is not fully specified. 
    at playground.MyModule.configure(MyModule.java:15) 

1 error 
    at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:354) 
    at com.google.inject.InjectorBuilder.initializeStatically(InjectorBuilder.java:152) 
    at com.google.inject.InjectorBuilder.build(InjectorBuilder.java:105) 
    at com.google.inject.Guice.createInjector(Guice.java:92) 

Hata iletisini aramayı denedim, ancak herhangi bir yararlı ipucu bulamadım. Ayrıca Guice SSS'de jeneriklerin nasıl enjekte edileceğiyle ilgili bir soruya rastlarım. Ben configure yönteminde aşağıdaki bağlayıcı eklemek çalıştı:

bind(new TypeLiteral<StringOutput<Double>>() {}).toInstance(new StringOutput<Double>()); 

Ama başarının (aynı hata mesajı) olmadan

.

Birisi bana hata mesajını açıklayabilir ve bana bazı ipuçları verebilir mi? Teşekkürler.

cevap

27

Gördüğünüz sorun, büyük olasılıkla bind(Console.class) ifadesinden kaynaklanmaktadır. Aynı zamanda bir TypeLiteral kullanmalısınız. Ya da, bunlardan hiçbirini bağlayamazsınız ve JIT bağlamaları sizin için halleder, çünkü burada yer alan her iki tip de somut sınıflardır.

Console<Double> cons = 
    injector.getInstance(Key.get(new TypeLiteral<Console<Double>>(){})); 

Edit:

Ayrıca, Console ile almak gerekir bir TypeLiteral kullandığınız sırf Bir örneğine bağlamak gerekmez. Sadece yapabilirsiniz: Elbette

bind(new TypeLiteral<Console<Double>>(){}); 

, ben sadece kullanarak enjektörden Console bu durumda o atlamak ve geri alabilirsem yukarıda dediğim gibi bir KeyTypeLiteral dayanan ve kapalı olacağını bağlayıcı.

+0

Teşekkürler. Bir TypeLitteral Console için nasıl bağlanacağından emin değilim çünkü bir StringOutput örneği olmayan bir Konsol örneği oluşturamıyorum. Detay verir misin – paradigmatic

+0

Benim düzenlemeye bakın ... toInstance() kullanmanız gerekmez. – ColinD

+0

Sadece denedim. Sadece her iki tip litteral tanımladığımda çalışır ve örneği almak için anahtarı kullanır. Bu yüzden bağlayıcıyı açık yapamıyorum. – paradigmatic

İlgili konular