繁体   English   中英

是否可以使用 Koin 进行动态依赖注入

[英]Is Dynamic Dependency Injection with Koin possible

我正在调查当前Android应用程序中的Koin依赖注入库。

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

我想做的是为我拥有的每种类型的后台工作动态注入一个 lambda。

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

科因模块:

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)

是的,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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM