Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger2 Basics - Field Injection - Not working

I am trying to do Field Injection using Dagger2. I realize I need to call inject manually in case of method injection. I am primarily trying to inject an Engine for a Car. The Engine is decided at runtime, and injected.

The data goes like this

CarInterface

import dagger.Binds;

public interface Car {  

    public void run();
}

Car Implementation

public class Volkswagen implements Car {

@Inject
public Engine engine;

    public void run() {
        System.out.println("About to Run");
        engine.start();
    }
}

Engine Interface

public interface Engine {
    public String start();
}

Engine Implementation

public class Ferrari4Cylinder implements Engine {

    @Override
    public String start() {
        return "Ignition----Vroom-- Vroom-- Sweet Purring Sound";
    }
}

Car Module

public  class CarModule{
    @Provides @Singleton
    Car provideCar(){
        return new Volkswagen();
    }   
}

Engine Module

@Module
public class EngineModule {
    @Provides @Singleton
    public Engine provideEngine(){
        return new Ferrari4Cylinder();
    }
}

Component Class

@Singleton
@Component(modules = {CarModule.class, EngineModule.class})
public interface MyCarComponent {
    public Car provideCar();
    void inject(Car car);
}

Main Method

public class Main {

    public static void main(String[] args) {
        MyCarComponent carComponent= DaggerMyCarComponent.builder().build();
        Car car = carComponent.provideCar();    
        carComponent.inject(car);
        car.run();
    }
}

For some reason : The Car.run() Method always returns null, as the Engine is never Injected. Exception in thread "main" java.lang.NullPointerException

Can anybody help out on what is happenning here?

Update 9/02/2016 : I figured out that the following changing the component to point to the actual implementation works as shown below. Not sure why the other one does not, but it helped me move forward on the issue.

@Singleton
@Component(modules = {CarModule.class, EngineModule.class})
public interface MyCarComponent {
    public Volkswagen provideCar();
    void inject(Volkswagen car);
}

Hope this helps folks trying to solve the Field Injection issues in Dagger.

like image 282
Jamie J Avatar asked Sep 14 '25 13:09

Jamie J


1 Answers

You need to annotate your Engine field with @Inject. I also believe you'll need to provide the implemented class (Volkswagen as opposed to just Car) to your inject method.

public class Volkswagen implements Car {

  @Inject public Engine engine;

  public void run() {
    System.out.println("About to Run");

    engine.start();
  }
}

--

@Singleton
@Component(modules = {CarModule.class, EngineModule.class})
public interface MyCarComponent {

  public Car provideCar();
  void inject(Volkswagen car);

}
like image 136
ootinii Avatar answered Sep 16 '25 01:09

ootinii