Dagger: class 无法与钥匙绑定
Dagger: class could not be bound with key
我是第一次尝试 dagger,在配置模块后,我收到一个我不明白的错误。
我的代码是:
public class Parrot {
private Language language;
@Inject
public Parrot(Language language) {
this.language = language;
}
public void sayHello() {
System.out.println(language.getSalute());
}
}
public interface Language {
public String getSalute();
}
public class EnglishLanguage implements Language {
@Override
public String getSalute() {
return "Hello!";
}
}
我的模块是
@Module(
injects = Language.class
)
public class PetShopModule {
@Provides Parrot provideParrot(Parrot parrot){
return parrot;
}
}
在代码中我是这样使用的
EnglishLanguage lang=SystemApp.getSystemLanguage();
ObjectGraph objectGraph = ObjectGraph.create(new PetShopModule());
objectGraph.inject(myLanguage);
Parrot parrot = objectGraph.get(Parrot.class);
编译器抱怨:
error: com.example.petshop.Language could not be bound
with key com.example.petshop.Language required by com.example.petshop.PetShopModule
for com.example.petshop.PetShopModule
我做错了什么?
注意:这只是一个简化的例子,在真实代码中EnglishLanguage是一个系统class,我不能修改也不能创建它,只是参考一下
与其评论你做错了什么,不如给出正确的例子,并解释那里发生了什么。
这段代码非常完美,保持原样:
public class Parrot {
private Language language;
@Inject
public Parrot(Language language) {
this.language = language;
}
public void sayHello() {
System.out.println(language.getSalute());
}
}
public interface Language {
public String getSalute();
}
public class EnglishLanguage implements Language {
@Override
public String getSalute() {
return "Hello!";
}
}
通过 Parrot
构造函数上的 @Inject
注释,你告诉 Dagger,"Whenever I request an instance of Parrot
, use this constructor to instantiate it"。
Dagger 发现 Parrot
需要 Language
接口的一个实例,并试图找到一种方法来检索它。但是,由于 Language
是一个接口,Dagger 需要知道要使用哪种 具体 类型。
由于您无法编辑 EnglishLanguage
class,您需要为其编写一个 @Provider
方法:
@Module
public class PetshopModule {
@Provides
Language provideLanguage() {
return SystemApp.getSystemLanguage();
}
}
现在,您应该能够从 ObjectGraph
中获取 Parrot
的实例,如下所示:
ObjectGraph graph = ObjectGraph.create(new PetshopModule());
Parrot parrot = graph.get(Parrot.class);
我还没有测试过,这个应该可以。
如果您 能够修改 EnglishLanguage
class,您可以执行以下操作。用@Inject
注释EnglishLanguage
构造函数,并在Language
提供者方法中请求一个EnglishLanguage
实例:
public class EnglishLanguage implements Language {
@Inject
public EnglishLanguage() {
}
@Override
public String getSalute() {
return "Hello!";
}
}
@Module
public class PetshopModule {
@Provides
Language provideLanguage(EnglishLanguage language) {
return language;
}
}
在这种情况下,Dagger 查找 Language
提供程序方法,并将 EnglishLanguage
实例化为 return。
现有的答案是完美的,但没有解决我的不明案例。
如果您有一个基础 Activity 和几个 DI 助手 classes,请确保您的 Activity 正确地扩展了它!
基础Activityclass:
private fun initializeObjectGraph() {
activityObjectGraph = (application as App).getObjectGraph()
.plus(ActivityModule(this))
.plus(*getAdditionalModulesForObjectGraph())
}
protected open fun getAdditionalModulesForObjectGraph() = arrayOf<Any>()
abstract fun injectDependencies(activityObjectGraph: ObjectGraph): LifecycleReceiver
扩展中需要覆盖 Activity:
override fun injectDependencies(activityObjectGraph: ObjectGraph): LifecycleReceiver {
activityObjectGraph.plus(MyModule(this)).inject(this)
return DummyLifecycleReceiver
}
override fun getAdditionalModulesForObjectGraph(): Array<Any> = arrayOf(MyModule(this))
我是第一次尝试 dagger,在配置模块后,我收到一个我不明白的错误。
我的代码是:
public class Parrot {
private Language language;
@Inject
public Parrot(Language language) {
this.language = language;
}
public void sayHello() {
System.out.println(language.getSalute());
}
}
public interface Language {
public String getSalute();
}
public class EnglishLanguage implements Language {
@Override
public String getSalute() {
return "Hello!";
}
}
我的模块是
@Module(
injects = Language.class
)
public class PetShopModule {
@Provides Parrot provideParrot(Parrot parrot){
return parrot;
}
}
在代码中我是这样使用的
EnglishLanguage lang=SystemApp.getSystemLanguage();
ObjectGraph objectGraph = ObjectGraph.create(new PetShopModule());
objectGraph.inject(myLanguage);
Parrot parrot = objectGraph.get(Parrot.class);
编译器抱怨:
error: com.example.petshop.Language could not be bound
with key com.example.petshop.Language required by com.example.petshop.PetShopModule
for com.example.petshop.PetShopModule
我做错了什么?
注意:这只是一个简化的例子,在真实代码中EnglishLanguage是一个系统class,我不能修改也不能创建它,只是参考一下
与其评论你做错了什么,不如给出正确的例子,并解释那里发生了什么。
这段代码非常完美,保持原样:
public class Parrot {
private Language language;
@Inject
public Parrot(Language language) {
this.language = language;
}
public void sayHello() {
System.out.println(language.getSalute());
}
}
public interface Language {
public String getSalute();
}
public class EnglishLanguage implements Language {
@Override
public String getSalute() {
return "Hello!";
}
}
通过 Parrot
构造函数上的 @Inject
注释,你告诉 Dagger,"Whenever I request an instance of Parrot
, use this constructor to instantiate it"。
Dagger 发现 Parrot
需要 Language
接口的一个实例,并试图找到一种方法来检索它。但是,由于 Language
是一个接口,Dagger 需要知道要使用哪种 具体 类型。
由于您无法编辑 EnglishLanguage
class,您需要为其编写一个 @Provider
方法:
@Module
public class PetshopModule {
@Provides
Language provideLanguage() {
return SystemApp.getSystemLanguage();
}
}
现在,您应该能够从 ObjectGraph
中获取 Parrot
的实例,如下所示:
ObjectGraph graph = ObjectGraph.create(new PetshopModule());
Parrot parrot = graph.get(Parrot.class);
我还没有测试过,这个应该可以。
如果您 能够修改 EnglishLanguage
class,您可以执行以下操作。用@Inject
注释EnglishLanguage
构造函数,并在Language
提供者方法中请求一个EnglishLanguage
实例:
public class EnglishLanguage implements Language {
@Inject
public EnglishLanguage() {
}
@Override
public String getSalute() {
return "Hello!";
}
}
@Module
public class PetshopModule {
@Provides
Language provideLanguage(EnglishLanguage language) {
return language;
}
}
在这种情况下,Dagger 查找 Language
提供程序方法,并将 EnglishLanguage
实例化为 return。
现有的答案是完美的,但没有解决我的不明案例。
如果您有一个基础 Activity 和几个 DI 助手 classes,请确保您的 Activity 正确地扩展了它!
基础Activityclass:
private fun initializeObjectGraph() {
activityObjectGraph = (application as App).getObjectGraph()
.plus(ActivityModule(this))
.plus(*getAdditionalModulesForObjectGraph())
}
protected open fun getAdditionalModulesForObjectGraph() = arrayOf<Any>()
abstract fun injectDependencies(activityObjectGraph: ObjectGraph): LifecycleReceiver
扩展中需要覆盖 Activity:
override fun injectDependencies(activityObjectGraph: ObjectGraph): LifecycleReceiver {
activityObjectGraph.plus(MyModule(this)).inject(this)
return DummyLifecycleReceiver
}
override fun getAdditionalModulesForObjectGraph(): Array<Any> = arrayOf(MyModule(this))