Reputation: 167
I'm trying to incorporate Dagger2 into my app, but the object I'm trying to inject is always null
unless I manually call inject()
. I thought inject()
is necessary only for activities/services/fragments that are created by the system. Is it actually necessary to manually inject into all classes that have dependencies?
Here's my simple example:
public class Foo {
@Inject Bar bar;
...
}
I have a module to provide Bar
:
@Module
public final class BarModule {
public BarModule() {}
@Provides
Bar provideBar () {
return new Bar();
}
}
And then I have a central component:
@Singleton
@Component(modules = {BarModule.class})
public interface AppComponent {
Bar buildBar();
void inject(Foo foo);
}
In my application, I build the component:
DaggerAppComponent.builder().barModule(new BarModule()).build();
But, bar
is always null
, unless I also call inject()
:
Foo foo = new Foo();
DaggerAppComponent.builder().barModule(new BarModule()).build().inject(foo);
Is it really necessary to define/call inject for every single class that has a dependency? I don't see such inject() calls everywhere in example code, so I'm thinking there's something I'm doing fundamentally wrong.
EDIT
Based on @DavidMedenjak's answer, I tried:
public class Bar {
@Inject
Bar() {}
public int hello(int b) {
return b + 5;
}
}
Without a module or component, I now do:
Log.i(TAG, "Hello is " + bar.hello(5));
which returns an NPE because bar is null.
EDIT 2 I think the problem is that I didn't bootstrap the injection by creating the component and calling it. What I needed is:
AppComponent comp;
comp = DaggerAppComponent.create();
bar = comp.buildBar();
Which, for a one-level object, is non-sensical, but for a dependency chain, the component would create the rest of the objects in the chain.
Upvotes: 0
Views: 326
Reputation: 34532
I thought
inject()
is necessary only for activities/services/fragments that are created by the system.
Correct.
Is it actually necessary to manually inject into all classes that have dependencies?
Nope. You should use constructor injection whenever possible.
BarModule
. Avoid calling the constructor from @Provides
annotated method), you don't need a module to use constructor injectionAdd @Inject
to Bar
's constructor to signal Dagger how to create the object
class Bar {
@Inject Bar() {}
}
That's all there is to it. Dagger now knows how to create Bar
. Add scopes & qualifiers to the class, dependencies as constructor parameters.
Upvotes: 2