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

 

Представим, что мы даггер. Нам дали интерфейс компонента AppComponent

AppComponent (:app)

@Component(modules = [DataModule::class])
interface AppComponent {

   fun injectTasksActivity(tasksActivity: TasksActivity)

}

 От нас требуется создать класс-реализацию.

 

Даггер создавал класс DaggerAppComponent, а мы создадим MyAppComponent

MyAppComponent (:app)

class MyAppComponent: AppComponent {

   override fun injectTasksActivity(tasksActivity: TasksActivity) {
       TODO("Not yet implemented")
   }

}

 

Наш компонент должен уметь инджектить объекты в TasksActivity.

Самый простой вариант - это сделать так:

MyAppComponent (:app)

class MyAppComponent: AppComponent {
  
   override fun injectTasksActivity(tasksActivity: TasksActivity) {
       tasksActivity.database = Database()
   }
  
}

И оно даже будет работать.

Но у нас создание Database явно описано в даггер-модуле DataModule. Поэтому надо использовать его:

MyAppComponent (:app)

class MyAppComponent: AppComponent {

   private val dataModule = DataModule()

   override fun injectTasksActivity(tasksActivity: TasksActivity) {
       tasksActivity.database = dataModule.provideDatabase()
   }

}

Мы создаем экземпляр даггер-модуля, просим его создать нам Database и помещаем в TasksActivity. И это собственно вся работа компонента. Больше от него пока ничего не требуется.

Этот код является упрощенной версией того, что делает под капотом реальный компонент даггера. Билдер компонента мы тут не делаем, чтобы не усложнять. Нам главное видеть, как компонент создает и инджектит объекты.

 

Осталось в App классе вместо даггер компонента создавать и использовать наш компонент

App (:app)

class App: Application() {

    lateinit var appComponent: AppComponent

    override fun onCreate() {
        super.onCreate()
        // appComponent = DaggerAppComponent.create()
        appComponent = MyAppComponent()
    }
}

 

Код TasksActivity не меняется, т.к. он работает с интерфейсом AppComponent, и ему не важно, какая там внутри реализация

class TasksActivity : AppCompatActivity() {

   @Inject
   lateinit var database: Database

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_tasks)
       (applicationContext as App).appComponent.injectTasksActivity(this)
   }
}

Получаем от App нашу реализацию компонента и используем его для инджекта Database.

 

Схема объектов та же, что и раньше, только теперь там наш компонент вместо даггеровского

 

 

Результат

Чтобы нам лучше понимать, что происходит, мы создали и использовали свою реализацию компонента.

Внутри не оказалось ничего сложного. Компонент создает модули и использует их для создания объекта. И эти объекты потом просто вставляет в Activity. Т.е. компонент - это просто фабрика, которая создает для нас объекты.

В следующем уроке немного усложним пример, добавив Context в процесс создания объекта Database.


Присоединяйтесь к нам в Telegram:

- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование 

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

- новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме 




Language

Автор сайта

Дмитрий Виноградов

Подробнее можно посмотреть или почитать.

Никакие другие люди не имеют к этому сайту никакого отношения и просто занимаются плагиатом.

Социальные сети

 

В канале я публикую ссылки на интересные и полезные статьи по Android

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



Группа ВКонтакте



Поддержка проекта

Яндекс
410011180491924

WebMoney
R248743991365
Z551306702056

Paypal