2017-03-31 42 views
1

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

+0

静态和DI是诅咒。你为什么认为你需要一个静态实例? –

+0

我需要一个静态实例,因为我在其他类中使用类的方法。我不想再次实例化每次我想要使用它(很多) –

+1

那么...注入实例?让它[@Singleton](https://github.com/google/guice/wiki/Scopes)? –

回答

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寿命东西:它根本没关系,这是否是单一实例,或者每个使用它的类都有自己的实例。

+0

噢,是的,我想要的是为主类创建一个静态实例,因为我有多个getter,可以从多个类访问多次。 –

2

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

要直接回答标题中的问题(带构造函数中的参数的DI),可以将DI与构造函数参数混合,而不是注入Factory。尽管欢迎您手动编写一个,但Guice可以为您做这个assisted injection(请参阅FactoryModuleBuilder),或者您可以使用通过Dagger流行的等效代码生成解决方案AutoFactory

如果您尝试在Guice应用程序中初始化静态类的字段,Guice可以在创建注入器后立即为您做。只需在供给Guice的模块中调用requestStaticInjection即可。正如Andy Turner指出的那样,这会导致您错过Guice的一些好处:因为您正在静态注入实例,所以很少有机会在测试或其他类重用中提供替换实现。 Guice在其wiki的static injections section中描述了这一点:

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

静态成员不会在实例注入时注入。这个API不推荐用于一般用途,因为它与静态工厂有许多相同的问题:测试笨拙,它使依赖不透明,它依赖于全局状态。

最好的整体解决方案是在Andy's answer:适应你的应用程序使用DI,它会让它注入你会静态的对象。