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.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With