2013-02-08 23 views
5

adlı enjekte:Basit POJO var Guice singleton'ununu

public class MyPOJO { 
    @Inject 
    private Fizz fizz; 

    private Buzz buzz; 

    // rest of class omitted for brevity 
} 

Ben Fizz es iki tür de enjekte etmesiyle vardır öyle ki benim Guice modülünü yapılandırmak istiyorum:

  1. özel, küresel olarak tekil Fizz örneği; ve
  2. Diğer (özel olmayan) Fizz örnekleri

I MyPOJO özel/Singleton Örneğin enjekte verilsin. Benim modülünde Sonra

public class MyPOJO { 
    @Inject @Named("Special-Fizz") 
    private Fizz fizz; 

    private Buzz buzz; 

    // rest of class omitted for brevity 
} 

: Ben kodumu modifiye

public class MyModule extends AbstractModule { 
    @Override 
    public void configure() { 
     bind(Fizz.class).annotatedWith(
      Names.named("Special-Fizz")) 
      .to(Fizz.class); 

     // Other bindings here... 
    } 

    @Provides @Singleton 
    private Fizz providesFizz() { 
     return new Fizz(true, "Special", 12.0); 
    } 
} 

Ama (JUnit 4.10) Bu birim testi çalıştığınızda:

public class MyTest { 
    @Named("Special-Fizz") private Fizz specialFizz; 

    @Test 
    public void usingNamedShouldInjectSpecialFizz() { 
     MyModule mod = new MyModule(); 
     Injector injector = Guice.createInjector(mod); 

     specialFizz = injector.getInstance(Fizz.class); 

     Assert.assertTrue(specialFizz != null); 
    } 
} 

Bu geçirir. Çok uzak çok iyi. Ama specialFizz alanının adını değiştirin sonra eğer:

@Named("Special-Fuzz-This-Shouldnt-Work") private Fizz specialFizz; 

Ve testi, hala geçer yeniden çalıştırın. Niye ya?!? Nerede burdan gidiyorum? Şimdiden teşekkürler.

cevap

3

Çok garip. Guce, enjekte ettiği bir Named bağlayıcı bulamazsa şikayet etmelidir. Yine de testin biraz karıştı. injector.inject'un ne yaptığını bilmiyorum. injectMembers mu demek istediniz? POJO'nuzun bir örneğini almak ve beklediğiniz gibi çalıştığından emin olmak daha mantıklı olabilir. Belki bir şey gibi:

public class FizzTest { 

    public static class MyModule extends AbstractModule { 
    @Override 
    protected void configure() { 
    } 

    @Provides 
    @Singleton 
    @Named("Special-Fizz") 
    public Fizz providesFizz() { 
     return new Fizz(true); 
    } 
    } 

    public static class Fizz { 
    boolean special = false; 
    public Fizz() {} 
    public Fizz(boolean special) { 
     this.special = special; 
    } 
    } 

    public static class MyPOJO { 
    @Inject @Named("Special-Fizz") 
    private Fizz fizz; 

    @Inject 
    private Fizz otherFizz; 
    } 

    @Test 
    public void test() { 
    MyModule mod = new MyModule(); 
    Injector injector = Guice.createInjector(mod); 

    MyPOJO pojo = injector.getInstance(MyPOJO.class); 
    assertTrue(pojo.fizz.special); 
    assertTrue(!pojo.otherFizz.special); 
    } 

} 
+0

Teşekkür @condit (1) - bu soruyu yukarı yazarak kendi payıma bir hata oldu. Ben aslında injector.getInstance' değil 'injector.inject'' arıyorum olduğunu göstermek için benim orijinal soruyu kaydetmiştiniz. Bu senin için her şeyi değiştirir mi? Burada kullanmak benim için doğru değil mi? Eğer öyleyse, neden, ve nedir? Tekrar teşekkürler! – IAmYourFaja

+0

Testinizde, enjektörü her zaman size sağlayabilecek olan bir “Fizz” örneği için soruyorsunuz ('Sağlamanız' yönteminiz nedeniyle). Bunun yerine bir "MyPOJO" örneğini almak istediğinizi düşünüyorum. Aldığınız Fizz'in testin Fizz üyesi ile ilgisi olmadığını unutmayın. Bu yüzden '@ Named' değiştirilmesinin bu durumda bir etkisi olmaz. – condit

+0

Siz çivilenmişsiniz. Sadece 'MyPOJO' enjekte etmesini istedim ve özel fizzimle 'Fizz' özelliğini doğru şekilde enjekte ettim. Gizem çözüldü - sadece zayıf uygulanan bir test yöntemi. Tekrar teşekkürler! – IAmYourFaja

2

Guice, @Provides yöntemini görür ve Fizz'u enjekte etmek için bunu kullanır. Eğer Fizz özel bir örneğini olmasını istiyorsanız, providesFizz() yönteminden ek açıklamaları bırakın ve bunun yerine

bind(Fizz.class) 
    .annotatedWith(Names.named("Special-Fizz") 
    .toInstance(providesFizz()); 

Bu şekilde ile bağlayabilir, sen Guice tam olarak hangi Fizz "Özel Fizz" olarak kullanmak için söyle, yine de "normal olarak" Fizz enjekte izin verirken.

Yasal Uyarı: Sizinki gibi bir kurulum denemedim, ancak benzer bir tane kullandım. İşe yarayıp yaramadığını bana bildirin.

+0

Teşekkürler @Bradley T. Hughes (+1) - ** Ancak ** öneriniz hiçbir şey değişmez. Birim testi, 'Fizz' adını verdiğinizden bağımsız olarak geçer. İlginç olduğunu düşündüğüm bir şeyden bahsetmiştin. “Ben aslında senin gibi bir kurumu denemedim ... *” dedin, ama cevabından Guice kullanarak oldukça rahat görünüyorsun. Bu yüzden beni şaşırtıyor: * Bu, kullanıyorum tuhaf bir kurulum mu? * Guice * nokta * Sınıflar ve Ek Açıklamalar birlikte kullanmak için ne tür/config tam olarak hangi noktayı bulmak için kullanmak olduğunu düşündüm ... – IAmYourFaja

+0

.. . Burada sıradan olan bir şey yapıyorum? Öyleyse neden?!? Guice’in normal kullanımını nerede yanlış anlayabilirim? Tekrar teşekkürler! – IAmYourFaja

+0

Bence bu tuhaf bir kurulum değil. Ve dürüst olmak gerekirse, ben çok fazla Guice kullanmadım, bu yüzden kesinlikle uzman değilim.Fark, üzerinde çalıştığım kodun, iki farklı türde (her birinin tek bir örneği) enjekte edilmesi için aynı açıklamayı kullanmasıdır. –