我有一个接口A,有多个实现说B,C和D. 我正在使用guice辅助注入来创建这些类。类B和C在构造函数中使用相同的assister参数(比如b,c),而D有一个不同的参数(比如d)。 我实现这个的方式是有一个工厂AFactory有2个方法: create(int b,int c)和createD(int d) 在我的模块中,我创建了一个PrivateModule来将具体类绑定到工厂。
代码如下所示:
public static PrivateModule getAFactoryModule(final String factoryBindingKey,final Class<? extends A> targetClassToCreate) {
return new PrivateModule() {
@Override
public void configure() {
install(new FactoryModuleBuilder().implement(
A.class, targetClassToCreate).build(
AFactory.class));
bind(AFactory.class).annotatedWith(Names.named(factoryBindingKey)).to(
Key.get(AFactory.class));
expose(Key.get(AFactory.class, Names.named(factoryBindingKey)));
}
};
}
我这样称为PrivateModule:
install(getAFactoryModule("B", B.class));
install(getAFactoryModule("C", C.class));
install(getAFactoryModule("D", D.class));
但是,这给出了一个错误说:
com.guice.test.B has @AssistedInject constructors but none of them match the parameters in method com.guice.test.AFactory.createD(). Unable to create assisted inject
com.guice.test.C has @AssistedInject constructors but none of them match the parameters in method com.guice.test.AFactory.createD(). Unable to create assisted inject
com.guice.test.D has @AssistedInject constructors but none of them match the parameters in method com.guice.test.AFactory.create(). Unable to create assisted inject
似乎Guice正在尝试使用与预期不同的创建方法。知道如何解决这个问题吗?任何指针都将不胜感激!
谢谢!
答案 0 :(得分:3)
听起来你正在做一些不安全的事情 - 让你的一些工厂方法无法解决 - 而Guice很困惑。基本上,FactoryModuleBuilder生成以下代码:
@Named("B") public class GeneratedBClass implements AFactory {
A create(int b, int c) { return new B(...); }
A create(int d) { /* no implementation! */ }
}
@Named("C") public class GeneratedBClass implements AFactory {
A create(int b, int c) { return new C(...); }
A create(int d) { /* no implementation! */ }
}
@Named("D") public class GeneratedBClass implements AFactory {
A create(int b, int c) { /* no implementation! */ }
A create(int d) { return new D(...); }
}
这三个缺失的实现是Guice抱怨的原因:Guice无法为那些人找到一个好的实现,并且认为你希望他们连接起来。但是,除了Guice之外,你设计了一个非常危险的API:根据你的配置,你的一种方法会起作用,一种方法无法工作 - 这比DI的设计更危险。
我会将你的配置切换到仅切换&#34; B&#34;和&#34; C&#34;,并且让这两个人暴露了&#34; D&#34;:
public interface AFactory {
@Named("BorC") A create(int B, int C);
@Named("D") A create(int D);
}
install(new FactoryModuleBuilder()
.implement(A.class, Names.named("BorC"), targetClassToCreate)
.implement(D.class, Names.named("D"), D.class)
.build(AFactory.class));
...或者,因为你应该在编译时知道你是否要调用双参数或单参数构造函数,只需将D切换到它自己的工厂:
public interface DFactory {
D create(int D);
}
// If DFactory creates an A, you need implement(). Otherwise, this works.
install(new FactoryModuleBuilder().build(DFactory.class));