Skip to content

Instantly share code, notes, and snippets.

@Tagakov
Created January 22, 2019 11:17
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tagakov/811db9934b73dcb8a9a5e20cfede9f9b to your computer and use it in GitHub Desktop.
Save Tagakov/811db9934b73dcb8a9a5e20cfede9f9b to your computer and use it in GitHub Desktop.
import android.app.Activity
import androidx.fragment.app.Fragment
import android.app.Application
import android.app.Service
import android.view.View
import android.view.ViewParent
import com.bluelinelabs.conductor.Controller
import dagger.MapKey
import dagger.Module
import dagger.multibindings.Multibinds
import kotlin.reflect.KClass
interface ComponentDependencies
inline fun <reified T : ComponentDependencies> Application.findComponentDependencies() = (this as HasComponentDependencies).dependencies[T::class.java] as? T
?: depsNotFound<T>(this)
inline fun <reified T : ComponentDependencies> Activity.findComponentDependencies() = dependenciesProviderHolder.get<T>()
inline fun <reified T : ComponentDependencies> Service.findComponentDependencies() = dependenciesProviderHolder.get<T>()
inline fun <reified T : ComponentDependencies> Controller.findComponentDependencies() = dependenciesProviderHolder.get<T>()
inline fun <reified T : ComponentDependencies> View.findComponentDependencies() = dependenciesProviderHolder.get<T>()
inline fun <reified T : ComponentDependencies> Fragment.findComponentDependencies() = dependenciesProviderHolder.get<T>()
inline fun <reified T : ComponentDependencies> HasComponentDependencies.get(): T = dependencies[T::class.java] as? T ?: depsNotFound<T>(this)
inline fun <reified T : ComponentDependencies> depsNotFound(dependenciesHolder: Any): Nothing = throw IllegalStateException("Dependencies ${T::class.java.name} not found in $dependenciesHolder")
val Activity.dependenciesProviderHolder
get() = application as HasComponentDependencies
val Service.dependenciesProviderHolder
get() = application as HasComponentDependencies
val Controller.dependenciesProviderHolder: HasComponentDependencies
get() {
var ancestor: Controller? = parentController
while (ancestor !is HasComponentDependencies?) {
ancestor = ancestor?.parentController
}
return ancestor
?: activity as? HasComponentDependencies
?: activity?.application as? HasComponentDependencies
?: throw IllegalStateException("Can not find suitable dagger provider for $this")
}
val View.dependenciesProviderHolder: HasComponentDependencies
get() {
var ancestor: ViewParent? = parent
while (ancestor !is HasComponentDependencies?) {
ancestor = ancestor?.parent
}
return ancestor
?: context as? HasComponentDependencies
?: context.applicationContext as? HasComponentDependencies
?: throw IllegalStateException("Can not find suitable dagger provider for $this")
}
val Fragment.dependenciesProviderHolder: HasComponentDependencies
get() {
var ancestor: Fragment? = parentFragment
while (ancestor !is HasComponentDependencies?) {
ancestor = ancestor?.parentFragment
}
return ancestor
?: activity as? HasComponentDependencies
?: activity?.application as? HasComponentDependencies
?: throw IllegalStateException("Can not find suitable dagger provider for $this")
}
typealias ComponentDependenciesProvider = Map<Class<out ComponentDependencies>, @JvmSuppressWildcards ComponentDependencies>
interface HasComponentDependencies {
val dependencies: ComponentDependenciesProvider
}
@MapKey
@Target(AnnotationTarget.FUNCTION)
annotation class ComponentDependenciesKey(val value: KClass<out ComponentDependencies>)
@Module
abstract class ComponentDependenciesModule private constructor() {
@Multibinds
abstract fun componentDependencies(): ComponentDependenciesProvider
}
/*
The commented code below is an example of a dagger module which provides gradle module's component dependencies from main application
internal typealias Deps = /*? extends */ComponentDependencies
internal typealias Component = dagger.Component
@dagger.Module
internal interface BindingModule {
@Binds
@IntoMap
@ComponentDependenciesKey(Deps::class)
fun providePanoramaDependencies(component: Component): ComponentDependencies
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment