我有一种情况,当我初始化我的一些类时,我需要注入一些字段(例如对工厂的引用等),而其他一些是动态的并且在运行时创建(例如用户名等)。如何使用GUICE框架构造此类对象?
简单地注释我需要注入@Inject
的字段不起作用,因为在使用构造函数创建对象时似乎没有设置它们。例如:
class C {
@Inject
private FactoryClass toBeInjected;
private ConfigurationField passedIn;
public C(ConfigurationField passedIn) {
this.passedIn = passedIn;
}
}
如果我的理解是正确的(我可能是错的),我通过C
而不是通过Guice创建new
的新实例的事实意味着不会发生注入。我确实需要在构造函数中传递这些参数,但也需要注入一些字段 - 所以我该如何解决这个问题?
答案 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对象一样,它们可以直接调用构造函数。)
请注意,此设计在以下几个方面特别有用:
C.Factory
的任何实现,并让它返回您想要的任何实例。这可以包括C或其工厂的测试双打:手动或使用Mockito,EasyMock,JMock或任何其他模拟框架创建的假货,模拟或间谍。