Hussain Memmedova
Hussain Memmedova

Reputation: 29

Dagger 2 injection of fields inside classes other than Activities

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

Answers (1)

David Rawson
David Rawson

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

Related Questions