Koin是否可能进行动态依赖注入

时间:2019-11-29 13:03:37

标签: android koin

我正在研究当前Koin应用程序中的Android依赖项注入库。

我有一个CoroutineWorker,可以完成我的所有后台工作。

我想做的是为我拥有的每种背景工作动态地注入一个lambda。

我有以下有效的代码,但是它不是动态的

Koin模块:

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
    }
}

还有我的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)
    }
}

有什么方法可以让我在运行时指定不同的lambda注入我的CoroutineWorker

例如,如果我的lambda Koin模块定义了10个lambda,则

BackgroundLambdaName_0 - BackgroundLambdaName_9

然后在开始我的独特背景工作时,如下所示:

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)

1 个答案:

答案 0 :(得分:2)

是的,至少Koin 2完全有可能。

我想为您准备的第一个创建模块是'lambdaModule'

val coffeeAppModule = module {
    single { CoffeeMaker(get(), get()) }
    single<Pump> { Thermosiphon(get()) }
    single<Heater> { ElectricHeater() }
}

然后动态加载模块并在不需要时卸载。

    // after start
loadKoinModules(coffeeAppModule)

// resolve CoffeeMaker
get()<CoffeeMaker>

// drop module's definitions & instances when you don't need it anymore
unloadKoinModules(coffeeAppModule)

请参考库的维护者,在这里您可以找到更多 https://medium.com/koin-developers/ready-for-koin-2-0-2722ab59cac3