我正在使用Guice进行辅助注射。这是一个标准方案:
Class TargetType {
@Inject
TargetType(@Assisted Param1 assistedParam, InjectedType injectedType)
{
/* ... */
}
}
Class InjectedType {
@Inject
injectedType(OtherInjectedType otherInjectedType)
{
/* ... */
}
}
现在我可以使用Guice工厂来调用TargetTypeFactory.create(assistedArg /* instanceof Param1 */)
,并愉快地获取我的TargetType
实例,其中InjectedType
的实例由Guice注入。
我的问题是:如果我希望InjectedType
引用正在创建的TargetType
的实例,该怎么办?换句话说,我想:
Class TargetType {
@Inject
TargetType(@Assisted Param1 assistedParam, InjectedType injectedType)
{
}
}
Class InjectedType {
@Inject
injectedType(/* How to get this? -> */ TargetType constructedTargetType, OtherInjectedType otherInjectedType)
{
}
}
我当前的解决方法非常难看:我在没有TargetType
的情况下手动创建InjectedType
,然后我使用InjectedTypeFactory
获取InjectedType
实例并调用{{1} } setInjectedType(InjectedType)
实例上的方法。 Ungh!
答案 0 :(得分:1)
有趣的问题。我不认为有一个完全干净的解决方案,但也许这种基于儿童注射器的解决方案将适合您:
首先,创建一个自定义guice绑定注释供您自己使用:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@BindingAnnotation
public @interface JamrozikParam {}
然后,将TargetType
更改为如下所示:
class TargetType {
@Inject
TargetType(@JamrozikParam Param1 assistedParam, InjectedType injectedType)
{
}
}
保持InjectedType
原样。
现在,您将获得TargetType
的实例:
Injector topInjector = Guice.createInjector(/* Your modules here */);
// Note that the modules used there can't mention TargetType or InjectedType
// Now many lines later
Param1 myP1val;
myP1val = // ... however that was computed
Injector childInjector = topInjector.childInjector(new Param1Module(myP1val));
TargetType t1 = childInjector.getInstance(TargetType.class);
Param1Module
是一个类似于以下的类:
public class Param1Module extends AbstractModule {
private final Param1 p1val;
public Param1Module(Param1 p1val) {this.p1val = p1val;}
protected void configure() {
bind(Param1.class).annotatedWith(JamrozikParam.class).toInstance(p1val);
bind(TargetType.class).in(Singleton.class);
bind(InjectedType.class).in(Singleton.class);
}
}
请注意,为了使其工作,Guice将创建一个代理来解决循环依赖。我建议您更轻松地创建代理,并使InjectedType
实现一个接口,让TargetType
注入该接口而不是直接注入InjectedType
,然后将该接口绑定到{{1 }}。否则,guice将不得不做一些可怕的字节码重写,而这只是在寻找麻烦。
我强烈建议您查看整个问题并重构事情,这样您就不需要这样做了。也许你的两个对象不需要在构造函数中相互了解?例如,您可以通过浏览一些主管对象将它们作为方法参数传递给彼此:
InjectedType