Reputation: 5664
I am investigating Koin
dependency injection library in my current Android
application.
I have a CoroutineWorker
that completes all my background work.
What I would like to do is Dynamically inject a lambda for each type of background work I have.
I have the following code that works, however it is not Dynamic
Koin Module:
const val BackgroundLambdaName: String = "back-ground-lambda"
val lambdaModule = module {
single(qualifier = named(BackgroundLambdaName)) {
background
}
}
private val background: suspend CoroutineScope.(Service) -> Unit = { service: Service ->
val limit: Int = 200
var offset: Int = 0
loop@ while (true) {
val networkResponse = service.move(options = mutableMapOf("limit" to limit, "offset" to offset))
if (networkResponse.next == null) {
break@loop
}
offset += limit
}
}
And my CoroutineWorker
:
class BackgroundWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params), KoinComponent {
private val service: Service by inject()
private val x_background: suspend CoroutineScope.(Service) -> Unit by inject(qualifier = named(BackgroundLambdaName))
override suspend fun doWork(): Result = coroutineScope {
withContext(Dispatchers.IO) {
downloadSynchronously(this)
Result.success()
}
}
private suspend fun downloadSynchronously(coroutineScope: CoroutineScope) {
x_background(coroutineScope, service)
}
}
Is there any approach I can take that will allow me to specify different lambdas at runtime to inject into my CoroutineWorker
?
For example if my lambda Koin module had 10 lambdas defined
BackgroundLambdaName_0 - BackgroundLambdaName_9
Then when starting my unique background work as follows:
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresBatteryNotLow(true)
.setRequiresCharging(true)
.build()
val backgroundWorkRequest = OneTimeWorkRequestBuilder<BackgroundWorker>()
.setConstraints(constraints)
.setBackoffCriteria(
BackoffPolicy.EXPONENTIAL,
OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS
).build()
// DYNAMICALLY set qualifier = named(BackgroundLambdaName) to one of
// BackgroundLambdaName_0 - BackgroundLambdaName_9
WorkManager.getInstance(application).enqueueUniqueWork(UNIQUE_WORK_NAME, ExistingWorkPolicy.KEEP, backgroundWorkRequest)
Upvotes: 6
Views: 6185
Reputation: 2346
Yes it is possible with Koin 2 at least is totally possible.
First create module that would be needed I guess for you is 'lambdaModule'
val coffeeAppModule = module {
single { CoffeeMaker(get(), get()) }
single<Pump> { Thermosiphon(get()) }
single<Heater> { ElectricHeater() }
}
Then dynamically load the module and unload when you don't need anymore.
// after start
loadKoinModules(coffeeAppModule)
// resolve CoffeeMaker
get()<CoffeeMaker>
// drop module's definitions & instances when you don't need it anymore
unloadKoinModules(coffeeAppModule)
please refer to maintainer of the library here you can find more https://medium.com/koin-developers/ready-for-koin-2-0-2722ab59cac3
Upvotes: 11