Поиск…


Синтаксис

  • @Module
  • @Component (dependencies = {OtherComponent.class}, modules = {ModuleA.class, ModuleB.class})
  • DaggerMyComponent.create ()
  • DaggerMyComponent.builder (). MyModule (newMyModule ()). Создать ()

замечания

Не путать с кинжалом по квадрату, предшественником кинжалом 2.

Настройка компонентов для инъекций приложений и активности

Базовый AppComponent который зависит от одного AppModule для предоставления общесистемных одноэлементных объектов.

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

    void inject(App app);

    Context provideContext();

    Gson provideGson();
}

Модуль для использования вместе с AppComponent который будет предоставлять свои одноэлементные объекты, например, экземпляр Gson для повторного использования во всем приложении.

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

Подклассовое приложение для настройки кинжала и синглтон-компонента.

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

Теперь компонент, зависящий от действия, который зависит от AppComponent чтобы получить доступ к объектам singleton.

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

    void inject(MainActivity activity);
}

И многократно используемый ActivityModule который будет обеспечивать основные зависимости, такие как 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();
    }
}

Собирая все вместе, мы настроены и можем внедрить нашу деятельность и обязательно использовать то же самое Gson всех приложений!

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

Пользовательские области

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

Области - это просто аннотации, и вы можете создавать свои собственные, где это необходимо.

Инъекция конструктора

Занятия без зависимостей могут быть легко созданы кинжалом.

public class Engine {

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

Этот класс может быть предоставлен любым компонентом. Он не имеет никаких зависимостей и не имеет ограничений . Дополнительного кода не требуется.


Зависимости объявляются как параметры в конструкторе. Кинжал вызовет конструктор и предоставит зависимости, если эти зависимости могут быть предоставлены.

public class Car {

    private Engine engine;

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

Этот класс может быть предоставлен каждым компонентом, если этот компонент может также обеспечить все его зависимости - Engine в этом случае. Так как Engine также может быть инжектирован конструктором, любой компонент может обеспечить Car .

Вы можете использовать инъекцию конструктора, когда все зависимости могут быть предоставлены компонентом. Компонент может обеспечить зависимость, если

  • он может создать его, используя инъекцию конструктора
  • модуль компонента может обеспечить его
  • он может быть предоставлен родительским компонентом (если он является @Subcomponent )
  • он может использовать объект, подвергаемый компоненту, зависящему от (зависимостей компонентов)

Использование @Subcomponent вместо @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);
    }
}

Как добавить кинжал 2 в build.gradle

Начиная с выпуска Gradle 2.2, использование плагина android-apt больше не используется. Должен использоваться следующий способ настройки кинжала 2. Для более старой версии Gradle используйте предыдущий метод, показанный ниже.

Для 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'
}

Для Gradle <2.2

Чтобы использовать Dagger 2, необходимо добавить плагин android-apt , добавьте его в root build.gradle:

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

Затем build.gradle модуля приложения должен содержать:

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

Ссылка: https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2

Создание компонента из нескольких модулей

Dagger 2 поддерживает создание компонента из нескольких модулей. Вы можете создать свой компонент таким образом:

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

Затем два модуля ссылок GeneralPurposeModule и SpecificModule могут быть реализованы следующим образом:

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

Во время фазы ввода зависимостей компонент будет брать объекты из обоих модулей в соответствии с потребностями.

Этот подход очень полезен с точки зрения модульности . В этом примере используется модуль общего назначения, используемый для создания таких компонентов, как объект Retrofit (используемый для обработки сетевой связи) и PropertiesReader (отвечающий за обработку файлов конфигурации). Существует также специальный модуль, который обрабатывает создание конкретных контроллеров и классов обслуживания в отношении этого конкретного компонента приложения.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow