Tudor
Tudor

Reputation: 1578

Constructor injection Dagger 2

I can't inject dependencies through the constructor and I'm sure that I'm doing something wrong. I have the following:

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

  @Override
  public String toString() { return "Water + ";}
}
public class Heater {
    @Inject
    public Heater() {}

    @Override
    public String toString() {return " heater";}
}

public class Aeropress {
    Water mWater;
    Heater mHeater;

    @Inject
    public Aeropress(Water water, Heater heater) {
        mWater = water;
        mHeater = heater;
    }

    @Override
    public String toString() {
        return mWater.toString() + mHeater.toString();
    }
}
public class LoginActivity extends AppCompatActivity{
   @Inject Aeropress aeropress;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      Log.e("* 69 * LoginActivity *", "onCreate " + aeropress);
}

The code in activity prints null so dagger doesn't inject anything. Any idea how to solve this without using @provide ? What am I missing ?

Upvotes: 1

Views: 336

Answers (1)

Tudor
Tudor

Reputation: 1578

In order to do this you have to do 2 things:
1. Declare a component with an inject method

@Component
public interface AeropressComponent {
    void inject(LoginActivity aeropress);
}

2. Build the dagger component in your activity and inject it

public class LoginActivity extends AppCompatActivity{
   @Inject Aeropress aeropress;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      DaggerAeropressComponent.builder().build().inject(this);
      /*DaggerAeropressComponent.create().inject(this);*/ //or this
      Log.e("* 69 * LoginActivity *", "onCreate " + aeropress);
}

After these modifications, it works like a charm without even creating a @Module class. The logic how I understand this and the reason why you need a component is that in order for dagger to inject a new instance into aeropress, it needs the container(the activity) where a reference of aeropress can be found. Also I just remembered now that the reason why @Inject fields can't be private is that dagger makes direct assignment between the reference and the created instance, in my example it does the following

LoginActivity.aeropress = Factory.createAeropress();

So without creating the component with the inject method, it can't know where to put the instance created with Factory.createAeropress(); If anyone can give me a better solution I'll mark the answer

Upvotes: 1

Related Questions