Reputation: 29
I have a class other than an Activity with injected fields :
public Class1 extends Class2 {
@Inject A a;
}
public Class2 extends Class3 {
@Inject B b;
}
public Class3 {
@Inject C c;
}
And I am providing Class1 like this:
@Provides
Class1 provideClass1(){
return new Class1();
}
My question : when providing Class1
will Dagger
inject B
and C
at the level of the super class? Or should I use constructor injection and call super inside the constructors?
Upvotes: 1
Views: 531
Reputation: 21427
Activity, Fragment, and Service are ideal sites for property injection because you have no control over their constructor and their instantiation is handled by the Android OS.
For the rest of your classes, constructor injection gives much more control and makes it easier to unit test. When writing a unit test, you simply pass in the test doubles you want when you are initialising the system under test. You also make it easier to write immutable classes fulfilling Effective Java item 15.
As for your other question, Dagger 2 is smart enough to inject properties in a super class. In other words, if you have a ConcreteService
extends BaseService
and you call component.inject(this)
inside ConcreteService
Dagger 2 will know to inject the properties of BaseService
if they are annotated correctly.
However, in your example you have a mix of property injection (the @Inject
annotations inside Class1
and Class2
) and constructor injector (the @Provides
method for Class1
which simply uses the constructor). This is not enough to have all the properties in the super classes of Class1
to be injected because you have specified the medium of provision of Class1
to be a simple call to the constructor. On the other hand, if you obtained the instance of Class1
through a component (through provision methods) or through requesting injection on a class which has a @Inject
annotated Class1
property then you would get a fully-formed instance.
Upvotes: 2