我正在探索Guice功能并面临一种奇怪的行为 - 当我将变量声明为
时@Inject
@Named("dragon")
Dragon dragon2;
注入按预期工作,但是当我想将dragon2声明为接口(它实现了Creature)时,i。即
@Inject
@Named("dragon")
Creature dragon2;
我收到错误
没有针对@com.google.inject.name.Named(value=dragon)
注释的warlock.rincewind.creatures.Creature绑定的实现。
这是我的提供者方法:
@Named("dragon")
@Provides
public Dragon providesDragon() {
Dragon d = new Dragon("Morkeleb");
return d;
}
我知道,有很多不同的方法可以克服这个问题(最简单的方法是将更改类型提供给Creature),但我试图找到这种限制的原因。
答案 0 :(得分:9)
考虑一下,例如:
interface Creature { }
class Dragon implements Creature { }
class Dog implements Creature { }
public class Kennel {
@Inject @Named("foo") Creature c;
}
public class KennelModule extends Abstract Module {
@Override
protected void configure() {
bind(Dragon.class).annotatedWith(Names.named("foo"));
bind(Dog.class).annotatedWith(Names.named("foo"));
}
}
您的注射如何知道是否在此处绑定Dragon
或Dog
?
它不能! 注入密钥不协变。您需要做的是,指定要注入的子类,并将其绑定到您要注入的接口或超类。换句话说:
public class KennelModule extends Abstract Module {
@Override
protected void configure() {
bind(Creature.class).annotatedWith(Names.named("foo").to(Dragon.class);
}
}
这将为您提供所需的行为。当然,您还可以专门为Dragon
绑定注入。