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.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow