Dagger 2 exposes a number of special annotations:
@Module for the classes whose methods provide dependencies
@Provides for the methods within @Module classes
@Inject to request a dependency (a constructor, a field, or a method)
@Component is a bridge interface between modules and injection
GitHub: https://github.com/google/dagger
UserGuide(Google): https://google.github.io/dagger/users-guide.html
Videos: https://google.github.io/dagger/resources.html
Vogella Tutorial: http://www.vogella.com/tutorials/Dagger/article.html
Codepath Tutorial: https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class VehicleModule {
@Provides @Singleton
Motor provideMotor(){
return new Motor();
}
@Provides @Singleton
Vehicle provideVehicle(){
return new Vehicle(new Motor());
}
}
Every provider (or method) must have the @Provides
annotation and the class must have the @Module
annotation. The @Singleton
annotation indicates that there will be only one instance of the object.
Now that you have the providers for your different models, you need to request them. Just as Vehicle
needs Motor
, you have to add the @Inject
annotation in the Vehicle
constructor as follows:
@Inject
public Vehicle(Motor motor){
this.motor = motor;
}
You can use the @Inject
annotation to request dependencies in the constructor, fields, or methods. In this example, I'm keeping the injection in the constructor.
The connection between the provider of dependencies, @Module
, and the classes requesting them through @Inject
is made using @Component
, which is an interface:
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = {VehicleModule.class})
public interface VehicleComponent {
Vehicle provideVehicle();
}
For the @Component
annotation, you have to specify which modules are going to be used. In this example VehicleModule
is used, which is defined in this example. If you need to use more modules, then just add them using a comma as a separator.
Now that you have every connection ready, you have to obtain an instance of this interface and invoke its methods to obtain the object you need:
VehicleComponent component = Dagger_VehicleComponent.builder().vehicleModule(new VehicleModule()).build();
vehicle = component.provideVehicle();
Toast.makeText(this, String.valueOf(vehicle.getSpeed()), Toast.LENGTH_SHORT).show();
When you try to create a new object of the interface with the @Component
annotation, you have to do it using the prefix Dagger_<NameOfTheComponentInterface>
, in this case Dagger_VehicleComponent
, and then use the builder method to call every module within.