Skip to content

Instantly share code, notes, and snippets.

@be1ski
Last active December 13, 2021 19:51
Show Gist options
  • Save be1ski/519027167dc467b34d99323615cb3512 to your computer and use it in GitHub Desktop.
Save be1ski/519027167dc467b34d99323615cb3512 to your computer and use it in GitHub Desktop.
/** Пример использования */
class MainActivity : AppCompatActivity(R.layout.activity_main) {
@Inject lateinit var fragmentFactory: FragmentFactory
private val component by nonConfigurationInstance {
DaggerActivityComponent.factory().create()
}
override fun onCreate(savedInstanceState: Bundle?) {
component.inject(this)
supportFragmentManager.fragmentFactory = fragmentFactory
super.onCreate(savedInstanceState)
supportFragmentManager
.beginTransaction()
.replace(containerId, FeatureFragment::class.java, null)
.commit()
}
}
/**
* Компонент, реализующий зависимости всех фичей.
* Находится в корневом модуле, который связывает зависимости (например :app)
*/
@Component(
modules = [
FeatureDependenciesModule::class,
FragmentFactoryModule::class
]
)
@ActivityScope
interface ActivityComponent {
fun inject(mainActivity: MainActivity)
@Component.Factory
interface Factory {
fun create(): ActivityComponent
}
}
/** Компонент фичи. Находится в модуле фичи. */
@Component(
dependencies = [FeatureDependencies::class]
)
@FragmentScope
interface FeatureComponent {
@Component.Factory
interface Factory {
fun create(dependencies: FeatureDependencies): FeatureComponent
}
}
/** Зависимости фичи. Находится в модуле фичи. */
class FeatureDependencies @Inject constructor(
val someExternalDependency: SomeExternalDependency
)
/**
* Рализация зависимостей одной конкретной фичи.
* Находится в корневом модуле, который связывает зависимости (например :app)
*/
@Module
abstract class FeatureDependenciesModule private constructor() {
@Binds
@IntoMap
@FragmentKey(FeatureFragment::class)
abstract fun provideFragment(fragment: FeatureFragment): Fragment
companion object {
@Provides
@JvmStatic
@ActivityScope
fun provideSomeExternalDependency() = SomeExternalDependency()
}
}
/** Фрагмент фичи. Находится в модуле фичи. */
class FeatureFragment @Inject constructor(
private val dependencies: FeatureDependencies
) : Fragment() {
private val component by nonConfigurationInstance {
DaggerFeatureComponent.factory().create(dependencies)
}
}
/** Утилитарный класс. Может находиться в :common:di */
class FragmentFactory @Inject constructor(
providers: Map<Class<out Fragment>, @JvmSuppressWildcards Provider<Fragment>>
) : androidx.fragment.app.FragmentFactory() {
private val providersByClassName = providers.mapKeys { (fragmentClass, _) -> fragmentClass.name }
override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
return providersByClassName[className]?.get() ?: super.instantiate(classLoader, className)
}
}
/** Утилитарный класс. Может находиться в :common:di */
@Module
abstract class FragmentFactoryModule private constructor() {
@Binds
abstract fun fragmentFactory(fragmentFactory: FragmentFactory): androidx.fragment.app.FragmentFactory
}
/** Утилитарный класс. Может находиться в :common:di */
@MapKey
@Target(FUNCTION, PROPERTY_GETTER)
@Retention(AnnotationRetention.RUNTIME)
annotation class FragmentKey(val value: KClass<out Fragment>)
@be1ski
Copy link
Author

be1ski commented Jul 7, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment