Android
Dague 2
Recherche…
Syntaxe
- @Module
- @Component (dépendances = {OtherComponent.class}, modules = {ModuleA.class, ModuleB.class})
- DaggerMyComponent.create ()
- DaggerMyComponent.builder (). MyModule (newMyModule ()). Create ()
Remarques
Ne pas confondre avec le poignard carré, le prédécesseur du poignard 2.
Configuration du composant pour l'injection d'application et d'activité
AppComponent
base qui dépend d'un seul AppModule
pour fournir des objets singleton à l'échelle de l'application.
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(App app);
Context provideContext();
Gson provideGson();
}
Un module à utiliser avec AppComponent
qui fournira ses objets singleton, par exemple une instance de Gson
à réutiliser dans toute l'application.
@Module
public class AppModule {
private final Application mApplication;
public AppModule(Application application) {
mApplication = application;
}
@Singleton
@Provides
Gson provideGson() {
return new Gson();
}
@Singleton
@Provides
Context provideContext() {
return mApplication;
}
}
Une application sous-classée pour configurer dagger et le composant singleton.
public class App extends Application {
@Inject
AppComponent mAppComponent;
@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent.builder().appModule(new AppModule(this)).build().inject(this);
}
public AppComponent getAppComponent() {
return mAppComponent;
}
}
Maintenant, un composant de portée d'activité qui dépend de AppComponent
pour accéder aux objets singleton.
@ActivityScope
@Component(dependencies = AppComponent.class, modules = ActivityModule.class)
public interface MainActivityComponent {
void inject(MainActivity activity);
}
Et un ActivityModule
réutilisable qui fournira des dépendances de base, comme un FragmentManager
@Module
public class ActivityModule {
private final AppCompatActivity mActivity;
public ActivityModule(AppCompatActivity activity) {
mActivity = activity;
}
@ActivityScope
public AppCompatActivity provideActivity() {
return mActivity;
}
@ActivityScope
public FragmentManager provideFragmentManager(AppCompatActivity activity) {
return activity.getSupportFragmentManager();
}
}
En mettant tout en place, nous sommes en mesure d'injecter notre activité et d'être sûr d'utiliser la même application Gson
partout!
public class MainActivity extends AppCompatActivity {
@Inject
Gson mGson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainActivityComponent.builder()
.appComponent(((App)getApplication()).getAppComponent())
.activityModule(new ActivityModule(this))
.build().inject(this);
}
}
Scopes personnalisés
@Scope
@Documented
@Retention(RUNTIME)
public @interface ActivityScope {
}
Les portées ne sont que des annotations et vous pouvez en créer de nouvelles si nécessaire.
Constructeur Injection
Les classes sans dépendances peuvent facilement être créées par dagger.
public class Engine {
@Inject // <-- Annotate your constructor.
public Engine() {
}
}
Cette classe peut être fournie par n'importe quel composant. Il n’a pas de dépendance et n’a pas de portée . Il n'y a pas d'autre code nécessaire.
Les dépendances sont déclarées comme paramètres dans le constructeur. Dagger appellera le constructeur et fournira les dépendances, tant que ces dépendances peuvent être fournies.
public class Car {
private Engine engine;
@Inject
public Car(Engine engine) {
this.engine = engine;
}
}
Cette classe peut être fournie par chaque composant si ce composant peut également fournir toutes ses dépendances - Engine
dans ce cas. Comme le Engine
peut également être injecté par un constructeur, tout composant peut fournir une Car
.
Vous pouvez utiliser l'injection de constructeur chaque fois que toutes les dépendances peuvent être fournies par le composant. Un composant peut fournir une dépendance, si
- il peut le créer en utilisant l'injection de constructeur
- un module du composant peut le fournir
- il peut être fourni par le composant parent (s'il s'agit d'un
@Subcomponent
) - il peut utiliser un objet exposé par un composant dont il dépend (dépendances des composants)
Utiliser @Subcomponent au lieu de @Component (dépendances = {...})
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(App app);
Context provideContext();
Gson provideGson();
MainActivityComponent mainActivityComponent(ActivityModule activityModule);
}
@ActivityScope
@Subcomponent(modules = ActivityModule.class)
public interface MainActivityComponent {
void inject(MainActivity activity);
}
public class MainActivity extends AppCompatActivity {
@Inject
Gson mGson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((App)getApplication()).getAppComponent()
.mainActivityComponent(new ActivityModule(this)).inject(this);
}
}
Comment ajouter Dagger 2 dans build.gradle
Depuis la sortie de Gradle 2.2, l'utilisation du plugin android-apt n'est plus utilisée. La méthode suivante pour configurer Dagger 2 doit être utilisée. Pour les anciennes versions de Gradle, utilisez la méthode précédente indiquée ci-dessous.
Pour Gradle> = 2.2
dependencies {
// apt command comes from the android-apt plugin
annotationProcessor 'com.google.dagger:dagger-compiler:2.8'
compile 'com.google.dagger:dagger:2.8'
provided 'javax.annotation:jsr250-api:1.0'
}
Pour Gradle <2.2
Pour utiliser Dagger 2, il faut ajouter le plugin android-apt
, ajouter ceci à la version build.gradle:
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
Ensuite, le build.gradle du module d'application doit contenir:
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
…
}
final DAGGER_VERSION = '2.0.2'
dependencies {
…
compile "com.google.dagger:dagger:${DAGGER_VERSION}"
apt "com.google.dagger:dagger-compiler:${DAGGER_VERSION}"
}
Référence: https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2
Création d'un composant à partir de plusieurs modules
Dagger 2 prend en charge la création d'un composant à partir de plusieurs modules. Vous pouvez créer votre composant de cette façon:
@Singleton
@Component(modules = {GeneralPurposeModule.class, SpecificModule.class})
public interface MyMultipleModuleComponent {
void inject(MyFragment myFragment);
void inject(MyService myService);
void inject(MyController myController);
void inject(MyActivity myActivity);
}
Les deux modules de référence GeneralPurposeModule
et SpecificModule
peuvent alors être implémentés comme suit:
GeneralPurposeModule.java
@Module
public class GeneralPurposeModule {
@Provides
@Singleton
public Retrofit getRetrofit(PropertiesReader propertiesReader, RetrofitHeaderInterceptor headerInterceptor){
// Logic here...
return retrofit;
}
@Provides
@Singleton
public PropertiesReader getPropertiesReader(){
return new PropertiesReader();
}
@Provides
@Singleton
public RetrofitHeaderInterceptor getRetrofitHeaderInterceptor(){
return new RetrofitHeaderInterceptor();
}
}
SpecificModule.java
@Singleton
@Module
public class SpecificModule {
@Provides @Singleton
public RetrofitController getRetrofitController(Retrofit retrofit){
RetrofitController retrofitController = new RetrofitController();
retrofitController.setRetrofit(retrofit);
return retrofitController;
}
@Provides @Singleton
public MyService getMyService(RetrofitController retrofitController){
MyService myService = new MyService();
myService.setRetrofitController(retrofitController);
return myService;
}
}
Pendant la phase d'injection de dépendance, le composant récupérera les objets des deux modules en fonction des besoins.
Cette approche est très utile en termes de modularité . Dans l'exemple, il existe un module général utilisé pour instancier des composants tels que l'objet Retrofit
(utilisé pour gérer la communication réseau) et un PropertiesReader
(chargé de gérer les fichiers de configuration). Il existe également un module spécifique qui gère l'instanciation de contrôleurs et de classes de service spécifiques par rapport à ce composant d'application spécifique.