Reputation: 32243
I'm trying for first time dagger and, after configuring the module, I get an error I don't understand.
My code is:
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!";
}
}
My module is
@Module(
injects = Language.class
)
public class PetShopModule {
@Provides Parrot provideParrot(Parrot parrot){
return parrot;
}
}
And in the code I use it this way
EnglishLanguage lang=SystemApp.getSystemLanguage();
ObjectGraph objectGraph = ObjectGraph.create(new PetShopModule());
objectGraph.inject(myLanguage);
Parrot parrot = objectGraph.get(Parrot.class);
The compiler complains with:
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
What do I am doing wrong?
Note: This is only a simplified example, in the real code the EnglishLanguage is a system class, and I can't modify nor create it, just get a reference
Upvotes: 7
Views: 2888
Reputation: 7989
The existing answer is perfect, but didn't solve my obscure case.
If you have a base Activity with a couple of DI helper classes, make sure your Activity that extends this does so properly!
Base Activity class:
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
Overrides needed in extension Activity:
override fun injectDependencies(activityObjectGraph: ObjectGraph): LifecycleReceiver {
activityObjectGraph.plus(MyModule(this)).inject(this)
return DummyLifecycleReceiver
}
override fun getAdditionalModulesForObjectGraph(): Array<Any> = arrayOf(MyModule(this))
Upvotes: 0
Reputation: 100448
Instead of commenting on what you're doing wrong, let's give the correct example, and explain what's happening there.
This snippet is perfect, and stays as it is:
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!";
}
}
With the @Inject
annotation on the Parrot
constructor, you're telling Dagger, "Whenever I request an instance of Parrot
, use this constructor to instantiate it".
Dagger sees that Parrot
needs an instance of the Language
interface, and tries to find a way to retrieve it. However, since Language
is an interface, Dagger needs to know which concrete type to use.
Since you cannot edit the EnglishLanguage
class, you'll need to write a @Provider
method for it:
@Module
public class PetshopModule {
@Provides
Language provideLanguage() {
return SystemApp.getSystemLanguage();
}
}
Now, you should be able to get an instance of Parrot
out of your ObjectGraph
, like this:
ObjectGraph graph = ObjectGraph.create(new PetshopModule());
Parrot parrot = graph.get(Parrot.class);
I have not tested this, bit this should work.
If you were able to modify the EnglishLanguage
class, you could do the following. Annotate the EnglishLanguage
constructor with @Inject
, and request an EnglishLanguage
instance in the Language
provider method:
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;
}
}
In this case, Dagger looks for the Language
provider method, and instantiates an EnglishLanguage
to return.
Upvotes: 14