Alex A.
2 min readOct 13, 2020

Как я внедрял Dagger2 в своём Android приложении

Данная заметка не претендует на какой-то “правильный” мануал о том как использовать Dagger2.

В своё время я уже успел поработать с различными IoC-контейнерами и фреймворками на различных языках и типах проектов, от игр до серверных приложений. Внедрение и первоначальная настройка Dagger 2 мне не показалась такой уж тривиальной и очевидной.

Я потратил несколько часов, чтобы разобраться в том, как это сделать правильно. Предлагаю вам ознакомиться с моими результатами и сэкономить немного времени.

Gradle

Для начала в Gradle добавляем зависимости.

dependencies {
...

implementation 'com.google.dagger:dagger:2.29'
annotationProcessor 'com.google.dagger:dagger-compiler:2.29'
...
}

Версия библиотеки последняя на момент написания заметки.

Создание обслуживающих структур

Далее я завел в папке Dagger2 (создана мною) набор файлов.

AppComponent.java имеет методы, через которые инициализируется внедрение зависимостей в Activity. Метод inject будет вызывается на необходимой Activity, которой требуется dependency injection.

@Singleton
@Component(modules = {ManagersProvides.class, InterfacesProvides.class})
public interface AppComponent {
void inject(PreloaderActivity activity);
void inject(MainActivity activity);
}

p.s. может быть, есть более унифицированное решение, чтобы не плодить методы inject на каждую Activity. Мне пока его найти не удалось.

В Component(modules=…) перечисляются модули, в которых определены методы создания экземпляров классов. Они будут инжектированы.

В модуле InterfaceProvides.java я перечисляю конкретные интерфейсы и их реализации.

@Module
public class InterfacesProvides {
@Provides
public Converters provideConverters() {
return new ImplConverters();
}
}

В модуле ManagersProvides.java я перечисляю менеджеры, которые используются у меня в проекте. Они могут иметь, а могут не иметь интерфейсы.

@Module
public class ManagersProvides {
@Singleton
@Provides
public SettingsManager provideSettingsManager(DataManager dataManager) {
return new ImplSettingsManager(dataManager);
}

@Singleton
@Provides
public DataManager provideDataManager() {
return new DataManager();
}

@Singleton
@Provides
public SessionManager provideSessionManager(SettingsManager settingsManager, DataManager dataManager) {
return new SessionManager(settingsManager, dataManager);
}
}

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

Такое разбиение на модули исключительно моё решение. У вас может быть своё.

Реализация AppComponent для инициализации инжектирования

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

public final class CoinsBook extends Application {

public static AppComponent appComponent = DaggerAppComponent.create();
...}

Внедрение зависимостей в Activity и ViewModel’s

На этом этапе проект готов к тому, чтобы использовать Dagger2. Теперь заинжектируем ViewModel в Activity. А потом и мои менеджеры (определенные выше) в ViewModel.

public class MainActivity extends NavigateActivity {

@Inject
protected MainActivityViewModel viewModel;
... public MainActivity() {

}
... @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

CoinsBook.appComponent.inject(this);
... }}

Внимание, Dagger2 не умеет инжектировать в private переменные.

public class MainActivityViewModel extends BaseObservable {

protected final DataManager dataManager;
protected final SettingsManager settingsManager;
protected final CurrencyManager currencyManager;
protected final Converters converters;;

@Inject
public MainActivityViewModel(DataManager dataManager,
SettingsManager settingsManager,
CurrencyManager currencyManager, Converters converters) {
this.dataManager = dataManager;
this.settingsManager = settingsManager;
this.currencyManager = currencyManager;

this.converters = converters;
}
...}

Обратите внимание, чтобы инжектировать в класс не являющийся Activity, конструктор помечается атрибутом @Inject, и в него передаются все необходимые зависимости (экземпляр зависимости будет создан Dagger2).

В случае с классом Activity этим атрибутом помечается только переменная, которую нужно инжектировать.

Итог

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

Coins Book в Google Play и группа ВК. Присоединяйтесь!

Alex A.

Ищу себя в этом мире. Разработчик и немного дизайнер. Читаю. Постоянно в поисках лучшей версии себя. Развиваю собственный амбициозный проект.