Guice / DI和混合注入以及在运行时传入的参数

时间:2015-05-13 18:45:28

标签: java dependency-injection guice

我有一种情况,当我初始化我的一些类时,我需要注入一些字段(例如对工厂的引用等),而其他一些是动态的并且在运行时创建(例如用户名等)。如何使用GUICE框架构造此类对象? 简单地注释我需要注入@Inject的字段不起作用,因为在使用构造函数创建对象时似乎没有设置它们。例如:

class C {
   @Inject
   private FactoryClass toBeInjected;

   private ConfigurationField passedIn;

   public C(ConfigurationField passedIn) {
      this.passedIn = passedIn;
   }
}

如果我的理解是正确的(我可能是错的),我通过C而不是通过Guice创建new的新实例的事实意味着不会发生注入。我确实需要在构造函数中传递这些参数,但也需要注入一些字段 - 所以我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

您正在寻找的是“按需”注射:

public static void main(String[] args) 
{
    Injector injector = Guice.createInjector(...);
    CreditCardProcessor creditCardProcessor = new PayPalCreditCardProcessor();
    injector.injectMembers(creditCardProcessor);
}

或静态的东西

@Override public void configure() {
   requestStaticInjection(ProcessorFactory.class);
   ...
 }

所有解释都非常好https://github.com/google/guice/wiki/Injections#on-demand-injection

注意:

  

这两件事都是代码味道,应该只是真正使用   用于将旧代码迁移到Guice。新代码不应使用这些   方法

答案 1 :(得分:3)

特别匹配"混合注射和参数传递的特征"将是Assisted Injection

class C {
  // Guice will automatically create an implementation of this interface.
  // This can be defined anywhere, but I like putting it in the class itself.
  interface Factory {
    C create(ConfigurationField passedIn);
  }

  @Inject
  private FactoryClass toBeInjected;

  private ConfigurationField passedIn;
  private SomeOtherDepIfYoudLike otherDep;

  @Inject public C(@Assisted ConfigurationField passedIn,
      SomeOtherDepIfYoudLike otherDep) {
    this.passedIn = passedIn;
    this.otherDep = otherDep;
  }
}

现在在您的模块中:

@Override public void configure() {
  install(new FactoryModuleBuilder().build(C.Factory.class));
}

现在当有人想要创建C时,他们可以避免直接调用构造函数;相反,他们注入一个C.Factory,他们通过他们选择的ConfigurationField实例并接收一个完全构造的,完全注入的C实例。 (与大多数精心设计的DI对象一样,它们可以直接调用构造函数。)

请注意,此设计在以下几个方面特别有用:

  • 您可以使用构造函数注入,将所有字段视为final,并将该对象视为不可变。
  • 如果您完全坚持使用构造函数注入,那么您的对象将永远不会处于部分初始化状态,并且您的API保持简单(调用构造函数并且您的对象已准备就绪)。
  • 为了进行测试,您可以编写C.Factory的任何实现,并让它返回您想要的任何实例。这可以包括C或其工厂的测试双打:手动或使用Mockito,EasyMock,JMock或任何其他模拟框架创建的假货,模拟或间谍。