Created
January 22, 2019 11:17
-
-
Save Tagakov/811db9934b73dcb8a9a5e20cfede9f9b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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