DI在构造函数中带有参数

时间:2017-03-31 19:12:07

标签: java dependency-injection guice

所以我在我的Java项目(Google Guice)中实现了一个依赖注入框架,一切都很好,我喜欢它但是有一个小问题; 我想创建一个主项目类的 static 实例(它实例化依赖项等)。但我不知道使用Guice实例化它的任何方法,我无法手动实例化它,因为我在它的构造函数中使用DI(我在构造函数中有对象)这意味着我无法访问class实例化类所需的非静态变量。 我尝试使用Provider但我无法真正理解绑定它的位置,因为我不想为主类提供接口(如果需要的话)。

2 个答案:

答案 0 :(得分:3)

如果您想要将一个类的静态实例与依赖注入混合在一起,那么您有点错过了依赖注入的点:您可以简单地注入该类的实例。

如果您想为您的注入器创建一个类的实例,请将其绑定到@Singleton范围:或者:

bind(YourClass.class).in(Singleton.class);

在您的模块configure()方法中,或

@Provides @Singleton YourClass provideYourClassInstance() {
  // ...
}

在您的模块中,或

@Singleton class YourClass {
  // ...
}

在实际的类声明中。

然后就像其他任何一样注入这个实例:

class SomeOtherClass {
  @Inject SomeOtherClass(YourClass instance) {
    // ... Do something with instance, like assign it to a field.
  }
}

关键是SomeOtherClass不应该对instance的生命周期有所了解:这不是一个单例实例,也不是每个使用它的类都无关紧要有自己的实例。

答案 1 :(得分:2)

根据问题,你可以在这里得到三个不同的答案。

要直接回答标题中的问题(在构造函数中使用参数DI),可以通过注入工厂来混合DI和constuctor参数。虽然欢迎您手动编写一个,但Guice可以assisted injection为您执行此操作(请参阅FactoryModuleBuilder),或者您可以使用Dagger中流行的等效代码生成的解决方案AutoFactory

如果您正在尝试在Guice应用程序中初始化静态类的字段,Guice可以在创建Injector后立即为您执行此操作。只需在您向Guice提供的模块中拨打requestStaticInjection即可。正如Andy Turner指出的那样,这会让你错过Guice的一些好处:因为你是静态注入实例,所以你很少有机会在测试或其他类重用中提供替换实现。 Guice在其维基的static injections section中对此进行了更多描述:

  

将应用程序从静态工厂迁移到Guice时,可以逐步更改。静电注射是一个有用的拐杖。通过获取对注入类型的访问而不自己注入,它使对象可以部分地参与依赖注入。 [...]

     

静态成员不会在实例注入时注入。建议不要将此API用于一般用途,因为它遇到许多与静态工厂相同的问题:测试时笨拙,依赖性不透明,依赖于全局状态。

最佳整体解决方案是Andy's answer:调整您的应用程序以使用DI,这将让它注入您原本会静态化的对象。