2016-03-10 119 views
1

我在我的應用程序中使用了guice框架。我有一個場景,其中一個類可能需要具有相同接口C的多個實例(但出於不同目的),如示例中所示。我正試圖用guice中的註釋工具來解決這個問題。Guice根據父實例註釋注入不同的實例

如下面的例子所示,我希望ConcreteImpl的配置也被guice注入。但問題是type1,type2和type3實例的配置可能不同。假設我擁有這些實例的配置,是否有一種方法可以根據請求配置的實例的上下文(由註釋表示)注入它們?

class A { 
     @Inject 
     public A(@Purpose1 C type1, @Purpose2 C type2, @Purpose3 C type3) { 

     } 
    } 

    interface C {} 

    class ConcreteImpl implements C { 
     @Inject 
     public ConcreteImpl(ConcreteImplConfig config) {} 
    } 

    class ConcreteImplConfig { 
     String pty1; 
     String pty2; 
    } 

我模塊綁定是這樣的 -

bind(C.class) 
      .annotatedWith(Purpose1.class) 
      .to(purpose1Cklass/**obtained from config**/); 

    bind(C.class) 
      .annotatedWith(Purpose2.class) 
      .to(purpose2Cklass/**obtained from config**/); 

    bind(C.class) 
      .annotatedWith(Purpose3.class) 
      .to(purpose3Cklass/**obtained from config**/); 

而這差不多就是我想要做的

bind(ConcreteImplConfig.class) 
      .requestedThrough(Purpose1.class) 
      .toInstance(purpose1config); 

    bind(ConcreteImplConfig.class) 
      .requestedThrough(Purpose2.class) 
      .toInstance(purpose2config); 

    bind(ConcreteImplConfig.class) 
      .requestedThrough(Purpose3.class) 
      .toInstance(purpose3config); 

我已經看了一眼輔助注射,可注射一個工廠,然後我們使用factory.create(config),但我不傾向於這樣做,因爲合同會變得稍微醜陋,並且我更多的是在我的應用程序開始時擁有所有配置,並且應該能夠注入它們。

+1

的可能的複製[如何實現「機器人腿」用例與谷歌吉斯?](http://stackoverflow.com/questions/35784112/how-to - 實現機器人腿部使用案例與谷歌guice) –

+0

哦,的確是的!我很難與這個例子相關聯。它現在很清楚。 :) 謝謝!! – amrk7

回答

2

這是Robot Leg Problem。您需要創建一個private module爲C.

abstract class CModule extends PrivateModule { 
    private final Class<? extends Annotation> annotation; 

    CModule(Class<? extends Annotation> annotation) { 
     this.annotation = annotation; 
    } 

    @Override protected void configure() { 
     bind(C.class).annotatedWith(annotation).to(C.class); 
     expose(C.class).annotatedWith(annotation); 

     bindConfig(); 
    } 

    abstract void bindConfig(); 
} 

public static void main(String[] args) { 
     Injector injector = Guice.createInjector(
       new CModule(Propsal1.class) { 
        @Override void bindConfig() { 
         bind(ConcreteImplConfig.class).toInstance(new ConcreteImplConfig()); 
        } 
       }, 
       new CModule(Propsal2.class) { 
        @Override void bindConfig() { 
         bind(ConcreteImplConfig.class).toInstance(new ConcreteImplConfig()); 
        } 
       }, 
       new CModule(Propsal2.class) { 
        @Override void bindConfig() { 
         bind(ConcreteImplConfig.class).toInstance(new ConcreteImplConfig()); 
        } 
       } 
       ); 
    }