Skip to content

Instantly share code, notes, and snippets.

@GabrielBrasileiro
Last active October 14, 2022 02:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save GabrielBrasileiro/7dbe145955dafb694d8d08f980d798c5 to your computer and use it in GitHub Desktop.
Save GabrielBrasileiro/7dbe145955dafb694d8d08f980d798c5 to your computer and use it in GitHub Desktop.
Koin extensions to solve type erasure of generic mappers
/**
* This will recover and inject your interface in your fragments or activities
*/
inline fun <reified I, reified O> ComponentCallbacks.injectMapper(): Lazy<Mapper<I, O>> {
return inject(named(identifier<I, O>()))
}
/**
* Activity, Fragment and KoinComponent usage
*
* Figurative class declaration
*/
class Component: KoinComponent, Activity(), Fragment() {
// Here we can recover the instance of mapper and use. :)
private val mapper by injectMapper<Int, String>()
}
/**
* This method indentifies the input and output returning a string.
*/
inline fun <reified I, reified O> identifier(): String {
val inputIdentifier = I::class.java.`package`.name + I::class.java.name
val outputIdentifier = O::class.java.`package`.name + O::class.java.name
return inputIdentifier + outputIdentifier
}
/**
* This method will declare your implementation inside module lambda
*/
inline fun <reified I, reified O> Module.mapper(
noinline definition: Definition<Mapper<I, O>>
): BeanDefinition<Mapper<I, O>> {
return factory(qualifier = named(identifier<I, O>()), definition = definition)
}
/**
* This will recover and inject your interface like the method get() in koin.
*/
inline fun <reified I, reified O> Scope.getMapper(): Mapper<I, O> {
return get(named(identifier<I, O>()))
}
/**
* This will recover and inject your interface in implementations of KoinComponent
*/
inline fun <reified I, reified O> KoinComponent.injectMapper(): Lazy<Mapper<I, O>> {
return inject(named(identifier<I, O>()))
}
/**
* This interface defines the control of input and output objects.
*/
interface Mapper<I, O> {
fun map(enter: I): O
}
/**
* Module usage
*/
module {
// Here is the implementation of mapper Mapper<PersonData, Person>.
mapper { PeopleMapper() }
// ... Declarations ...
// The param in method is Mapper<PersonData, Person>.
mapper { PeoplePageMapper(getMapper()) }
factory<PeopleRepository> {
// getMapper() recover the mapper and inject.
PeopleRepositoryImpl(get(), get(), getMapper(), getMapper())
}
}
@simplekjl
Copy link

Nice

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