2016-03-10 121 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()); 
        } 
       } 
       ); 
    }