Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Dagger2

## Задача

### Реализуйте ApplicationComponent
Это корень нашего дерева компонентов. Инициализируется в классе App, прокидывает в граф через Component Dependencies/Subcomponents ниже по графу следующие сущности:
- Context(Application) до FragmentProducerComponent и FragmentReceiverComponent.
Expand All @@ -12,3 +16,8 @@
Коммуникацию между Producer и Receiver осуществите через канал/StateFlow/Subject либо другую реализацию обсервера которая уже есть в графе. ViewModelProducer должна отправлять эвенты, ViewModelReceiver должна получать эвенты. Обсерверы должны прокидываться в конструкторы вьюмоделей и существовать в единственном экземпляре в Activity.
Флоу отправки эвента выглядит следующим образом:
Клик на кнопку button в FragmentProducer -> вызов метода вьюмодели -> проброс евента в обсервер -> евент ловится на стороне ViewModelReceiver -> евент передается FragmentReceiver и вызывается функция ru.otus.daggerhomework.FragmentReceiver#populateColor

## Решение

Решение базируется на Subcomponents.
В качестве канала коммуникации между франментами использован Channel.
16 changes: 16 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'

// dagger2
implementation 'com.google.dagger:dagger:2.42'
kapt 'com.google.dagger:dagger-compiler:2.42'

// coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'

//
/* lifecircle */
def lifecycle_version = "2.5.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"

/* extensions to simplify the fragment API */
implementation "androidx.fragment:fragment-ktx:1.5.5"
}
8 changes: 5 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ru.otus.daggerhomework">

<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.DaggerHomework">
<activity android:name=".MainActivity">
<activity
android:name=".presentation.Activity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
22 changes: 21 additions & 1 deletion app/src/main/java/ru/otus/daggerhomework/App.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
package ru.otus.daggerhomework

import android.app.Application
import android.content.Context
import ru.otus.daggerhomework.di.ApplicationComponent
import ru.otus.daggerhomework.di.DaggerApplicationComponent

class App :Application() {
/**
* `Custom application` приложения
*/
class App : Application() {

private lateinit var applicationComponent: ApplicationComponent

override fun onCreate() {
super.onCreate()
applicationComponent = DaggerApplicationComponent.factory().create(this)
}

companion object {

/** Получить [applicationComponent] на основе [context] */
fun appComponent(context: Context) =
(context.applicationContext as App).applicationComponent
}
}

This file was deleted.

20 changes: 0 additions & 20 deletions app/src/main/java/ru/otus/daggerhomework/ColorGenerator.kt

This file was deleted.

26 changes: 0 additions & 26 deletions app/src/main/java/ru/otus/daggerhomework/FragmentProducer.kt

This file was deleted.

31 changes: 0 additions & 31 deletions app/src/main/java/ru/otus/daggerhomework/FragmentReceiver.kt

This file was deleted.

12 changes: 0 additions & 12 deletions app/src/main/java/ru/otus/daggerhomework/MainActivity.kt

This file was deleted.

16 changes: 0 additions & 16 deletions app/src/main/java/ru/otus/daggerhomework/ViewModelProducer.kt

This file was deleted.

15 changes: 0 additions & 15 deletions app/src/main/java/ru/otus/daggerhomework/ViewModelReceiver.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ru.otus.daggerhomework.di

import android.content.Context
import dagger.BindsInstance
import dagger.Component
import ru.otus.daggerhomework.di.main.MainActivityComponent
import ru.otus.daggerhomework.di.utils.qualifiers.ApplicationContext

/**
* `Dagger` [Component] приложения
*/
@Component(modules = [ApplicationSubcomponentsModule::class])
interface ApplicationComponent {

/** Фабрика `Dagger` [Component]-а главного экрана */
val mainActivityComponentFactory: MainActivityComponent.Factory

/** Фабрика `Dagger` [Component]-а приложения */
@Component.Factory
interface Factory {

/** Создать [ApplicationComponent] на основе `Application` контекста [context] */
fun create(@BindsInstance @ApplicationContext context: Context): ApplicationComponent
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ru.otus.daggerhomework.di

import dagger.Module
import ru.otus.daggerhomework.di.main.MainActivityComponent

/**
* `Dagger` [Module] `subcomponent`-ов приложения
*/
@Module(subcomponents = [MainActivityComponent::class])
interface ApplicationSubcomponentsModule
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ru.otus.daggerhomework.di.main

import android.content.Context
import dagger.BindsInstance
import dagger.Component
import dagger.Subcomponent
import ru.otus.daggerhomework.di.producer.FragmentProducerComponent
import ru.otus.daggerhomework.di.receiver.FragmentReceiverComponent
import ru.otus.daggerhomework.di.utils.qualifiers.ActivityContext
import ru.otus.daggerhomework.di.utils.scopes.ActivityScope

/**
* `Dagger` [Component] главного экрана
*/
@ActivityScope
@Subcomponent(modules = [MainActivityModule::class, MainActivitySubcomponentsModule::class])
interface MainActivityComponent {

/** Фабрика `Dagger` [Component]-а Fragment`-а поставления цветов */
val fragmentProducerComponentFactory: FragmentProducerComponent.Factory

/** Фабрика `Dagger` [Component]-а Fragment`-а получения цветов */
val fragmentReceiverComponentFactory: FragmentReceiverComponent.Factory

/** Фабрика `Dagger` [Component]-а главного экрана */
@Subcomponent.Factory
interface Factory {

/** Создать [MainActivityComponent] на основе контекста `Activity` [context] */
fun create(@BindsInstance @ActivityContext context: Context): MainActivityComponent
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package ru.otus.daggerhomework.di.main

import dagger.Binds
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.channels.Channel
import ru.otus.daggerhomework.di.utils.scopes.ActivityScope
import ru.otus.daggerhomework.presentation.color.ColorGenerator
import ru.otus.daggerhomework.presentation.color.ColorGeneratorImpl

/**
* `Dagger` [Module] главного экрана
*/
@Module
interface MainActivityModule {

@Binds
fun bindColorGenerator(colorGenerator: ColorGeneratorImpl): ColorGenerator

companion object {

@ActivityScope
@Provides
fun provideChannel(): Channel<Int> = Channel(Channel.CONFLATED)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ru.otus.daggerhomework.di.main

import dagger.Module
import ru.otus.daggerhomework.di.producer.FragmentProducerComponent
import ru.otus.daggerhomework.di.receiver.FragmentReceiverComponent

/**
* `Dagger` [Module] `subcomponent`-ов главного экрана
*/
@Module(subcomponents = [FragmentProducerComponent::class, FragmentReceiverComponent::class])
interface MainActivitySubcomponentsModule
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ru.otus.daggerhomework.di.producer

import dagger.Component
import dagger.Subcomponent
import ru.otus.daggerhomework.di.utils.scopes.FragmentScope
import ru.otus.daggerhomework.presentation.producer.FragmentProducer

/**
* `Dagger` [Component] `Fragment`-а поставления цветов
*/
@FragmentScope
@Subcomponent(modules = [FragmentProducerModule::class])
interface FragmentProducerComponent {

/** Внедрить зависимости [FragmentProducer]-а */
fun inject(producer: FragmentProducer)

/** Фабрика `Dagger` [Component]-а Fragment`-а поставления цветов */
@Subcomponent.Factory
interface Factory {

/** Создать [FragmentProducerComponent] */
fun create(): FragmentProducerComponent
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ru.otus.daggerhomework.di.producer

import dagger.Binds
import dagger.Module
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.SendChannel

/**
* `Dagger` [Module] `Fragment`-а поставления цветов
*/
@Module
interface FragmentProducerModule {

@Binds
fun bindSendChannel(channel: Channel<Int>): SendChannel<Int>
}
Loading