Add utility loadService

This commit is contained in:
Him188 2021-08-05 12:49:39 +08:00
parent f4adc1232f
commit cf1c5d4d81
3 changed files with 47 additions and 0 deletions

View File

@ -13,6 +13,9 @@
package net.mamoe.mirai.utils
import android.util.Base64
import java.util.*
import kotlin.reflect.KClass
import kotlin.reflect.full.createInstance
public actual fun ByteArray.encodeBase64(): String {
@ -40,3 +43,16 @@ public actual inline fun <reified E> Throwable.unwrap(): Throwable {
?.also { it.addSuppressed(e) }
?: this
}
public actual fun <T : Any> loadService(clazz: KClass<out T>, fallbackImplementation: String?): T {
var suppressed: Throwable? = null
return ServiceLoader.load(clazz.java).firstOrNull()
?: runCatching {
Class.forName(fallbackImplementation).cast<Class<out T>>().kotlin.run { objectInstance ?: createInstance() }
}.onFailure {
suppressed = it
}.getOrNull()
?: throw NoSuchElementException("Could not find an implementation for service class ${clazz.qualifiedName}").apply {
if (suppressed != null) addSuppressed(suppressed)
}
}

View File

@ -0,0 +1,16 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.utils
import kotlin.reflect.KClass
public expect fun <T : Any> loadService(clazz: KClass<out T>, fallbackImplementation: String? = null): T
public inline fun <reified T : Any> loadService(fallbackImplementation: String? = null): T =
loadService(T::class, fallbackImplementation)

View File

@ -13,6 +13,8 @@
package net.mamoe.mirai.utils
import java.util.*
import kotlin.reflect.KClass
import kotlin.reflect.full.createInstance
public actual fun ByteArray.encodeBase64(): String {
@ -29,3 +31,16 @@ public actual inline fun <reified E> Throwable.unwrap(): Throwable {
?.also { it.addSuppressed(this) }
?: this
}
public actual fun <T : Any> loadService(clazz: KClass<out T>, fallbackImplementation: String?): T {
var suppressed: Throwable? = null
return ServiceLoader.load(clazz.java).firstOrNull()
?: runCatching {
Class.forName(fallbackImplementation).cast<Class<out T>>().kotlin.run { objectInstance ?: createInstance() }
}.onFailure {
suppressed = it
}.getOrNull()
?: throw NoSuchElementException("Could not find an implementation for service class ${clazz.qualifiedName}").apply {
if (suppressed != null) addSuppressed(suppressed)
}
}