Ricerca…


Sintassi

  • @Modulo
  • @Component (dependencies = {OtherComponent.class}, modules = {ModuleA.class, ModuleB.class})
  • DaggerMyComponent.create ()
  • DaggerMyComponent.builder (). Mymodule (newMyModule ()). Create ()

Osservazioni

Non confondere con il pugnale di quadrato, il predecessore del pugnale 2.

Configurazione dei componenti per l'iniezione di applicazioni e attività

Un AppComponent base che dipende da un singolo AppModule per fornire oggetti singleton a livello di applicazione.

@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {

    void inject(App app);

    Context provideContext();

    Gson provideGson();
}

Un modulo da utilizzare insieme a AppComponent che fornirà i suoi oggetti singleton, ad esempio un'istanza di Gson da riutilizzare nell'intera applicazione.

@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;
    }
}

Un'applicazione sottoclassata per l'impostazione di dagger e del componente 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;
    }
}

Ora un componente con ambito attività che dipende da AppComponent per accedere agli oggetti Singleton.

@ActivityScope
@Component(dependencies = AppComponent.class, modules = ActivityModule.class)
public interface MainActivityComponent {

    void inject(MainActivity activity);
}

E un ActivityModule riutilizzabile che fornirà dipendenze di base, come 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();
    }
}

Mettendo tutto insieme siamo pronti e possiamo iniettare la nostra attività ed essere sicuri di usare lo stesso Gson tutta l'app!

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);
    }
}

Ambiti personalizzati

@Scope
@Documented
@Retention(RUNTIME)
public @interface ActivityScope {
}

Gli ambiti sono solo annotazioni e puoi crearne di tuoi laddove necessario.

Costruttore di iniezione

Le classi senza dipendenze possono essere facilmente create dal pugnale.

public class Engine {

    @Inject // <-- Annotate your constructor.
    public Engine() {
    }
}

Questa classe può essere fornita da qualsiasi componente. Non ha dipendenze e non ha ambito . Non è necessario alcun altro codice.


Le dipendenze sono dichiarate come parametri nel costruttore. Dagger chiamerà il costruttore e fornirà le dipendenze, purché tali dipendenze possano essere fornite.

public class Car {

    private Engine engine;

    @Inject
    public Car(Engine engine) {
        this.engine = engine;
    }
}

Questa classe può essere fornita da ogni componente se questo componente può anche fornire tutte le sue dipendenze - Engine in questo caso. Poiché Engine può anche essere iniettato dal costruttore, qualsiasi componente può fornire Car .

È possibile utilizzare l'iniezione del costruttore ogni volta che tutte le dipendenze possono essere fornite dal componente. Un componente può fornire una dipendenza, se

  • può crearlo usando l'iniezione del costruttore
  • un modulo del componente può fornirlo
  • può essere fornito dal componente principale (se è un @Subcomponent )
  • può usare un oggetto esposto da un componente da cui dipende (dipendenze dei componenti)

Utilizzo di @Subcomponent anziché di @Component (dependencies = {...})

@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);
    }
}

Come aggiungere Dagger 2 in build.gradle

Dal rilascio di Gradle 2.2, l'uso del plugin per Android-apt non è più utilizzato. Deve essere usato il seguente metodo di impostazione di Dagger 2. Per la versione precedente di Gradle, utilizzare il metodo precedente mostrato di seguito.

Per 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'
}

Per Gradle <2.2

Per utilizzare Dagger 2 è necessario aggiungere il plugin per android-apt , aggiungere questo alla root build.gradle:

buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}

Quindi il build.gradle del modulo dell'applicazione dovrebbe contenere:

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}"
}

Riferimento: https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2

Creazione di un componente da più moduli

Dagger 2 supporta la creazione di un componente da più moduli. Puoi creare il tuo componente in questo modo:

@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);
}

I due moduli di riferimento GeneralPurposeModule e SpecificModule possono quindi essere implementati come segue:

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;
    }
}

Durante la fase di iniezione delle dipendenze, il componente prenderà gli oggetti da entrambi i moduli in base alle esigenze.

Questo approccio è molto utile in termini di modularità . Nell'esempio, esiste un modulo generico utilizzato per istanziare componenti come l'oggetto Retrofit (utilizzato per gestire le comunicazioni di rete) e un PropertiesReader (incaricato di gestire i file di configurazione). Esiste anche un modulo specifico che gestisce l'istanziazione di specifici controller e classi di servizio in relazione a quel componente specifico dell'applicazione.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow