Search code examples
androiddagger-2

Dagger2 how to perform constructor injection of a default constructor


Here is a scenario. Let's say there is a class A

Class A{

@Inject
public A(){}

}

And in my Activity

 public class MainActivity extends Activity{

    @Inject
    A a;

     @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    }
}

How to inject a in this scenario.


Solution

  • Ok first of all you need a module:

    @Module
    class SomeModule{
      @SomeScope
      @Provides
      A proivdeTheAInstance(){
       return new A();
      }
    }
    

    Then your component:

    @SomeScope
    @Component(modules = {A.class}, dependencies={HigherLowerDependencyComponent.class})
    interface SomeComponent{
     void inject(MainActivity activity);
    }
    

    After that in your activity, after you have performed build, in the onCreate

    DaggerSomeComponent.builder().higherLowerDependencnyComponent(implementationHere).build().inject(this)
    

    Than you can @Inject A

    But there is one problem. Constructor injection doesn't work like that. In order to perform Constructor Injection, your A() constructor should have at least one dependency. The @Inject annotation on that constructor doesn't call the A() but its dependencies, which in your case would be 0, thus making the @Inject in your A() constructor unnecessary. Your question would stand if your A constructor would be like this:

        @Inject
        public A(SomeDependency dependency){
         this.someDependency = dependency;
        }
    

    SomeDependency is going to be provided in the module as well:

    @Module
    class SomeModule{
      @SomeScope
      @Provides
      A proivdeTheAInstance(SomeDependency someDependency){ //now dagger will look to find this one
       return new A();
      }
    
    @SomeScope
      @Provides
      SomeDependency proivdeSomeDependencyInstance(){ //which is provided here 
       return new SomeDependency();
      }
    }
    

    And you are good to go as you were:

    class A{
    private SomeDependency someDependency;
     @Inject
     public A(SomeDependency someDependency){ //the inject will require the SomeDependency
      this.someDependency = someDependency;
      }
    }
    

    EDIT: If dagger already knows how to provide the instance there is no need for a Module, you can just perform @Inject above the constructor of the class A():

    class A{
        @Inject
        public A(){
        }
    }