Skip to content

Instantly share code, notes, and snippets.

@marcellogalhardo
Created February 25, 2023 16:14
Show Gist options
  • Save marcellogalhardo/27f68aac2958086ecf2669e201a62627 to your computer and use it in GitHub Desktop.
Save marcellogalhardo/27f68aac2958086ecf2669e201a62627 to your computer and use it in GitHub Desktop.
Simple dependency providers primitives.
package provider
internal class MutableProviderImpl<T>(
scope: ProviderScope? = null,
private val factory: InstanceFactory<T>? = null,
) : ReadWriteProvider<T> {
init {
require(scope is ProviderScopeImpl)
scope.listeners.add { value = null }
}
private var value: T? = null
override fun set(value: T) {
this.value = value
}
override fun get(): T {
if (value == null) {
value = factory?.invoke()
}
return requireNotNull(value)
}
}
@file:Suppress("FunctionName")
package provider
public fun <T : Any> LateInitProvider(): ReadWriteProvider<T> = MutableProviderImpl()
public fun <T> MutableProvider(): ReadWriteProvider<T?> = MutableProviderImpl()
public fun <T> MutableProvider(
factory: InstanceFactory<T>,
): ReadWriteProvider<T> = MutableProviderImpl(factory = factory)
public fun <T> SingleProvider(
factory: InstanceFactory<T>,
): ReadOnlyProvider<T> = MutableProviderImpl(factory = factory)
public fun <T> ScopedProvider(
scope: ProviderScope,
factory: InstanceFactory<T>,
): ReadOnlyProvider<T> = MutableProviderImpl(scope = scope, factory = factory)
public fun <T> TransientProvider(
factory: InstanceFactory<T>,
): ReadOnlyProvider<T> = TransientProviderImpl(factory = factory)
package provider
public sealed interface ProviderScope {
public fun clear()
}
public fun ProviderScope(): ProviderScope = ProviderScopeImpl()
package provider
internal class ProviderScopeImpl internal constructor(
var listeners: MutableSet<OnClearListener> = mutableSetOf(),
) : ProviderScope {
override fun clear() {
listeners.forEach { it.invoke() }
}
}
package provider
import kotlin.reflect.KProperty
public sealed interface ReadOnlyProvider<T> {
public fun get(): T
}
/**
* Permits property delegation of `val`s using `by` for [ReadOnlyProvider].
*/
@Suppress("NOTHING_TO_INLINE")
public inline operator fun <T> ReadOnlyProvider<T>.getValue(thisObj: Any?, property: KProperty<*>): T = get()
package provider
public sealed interface ReadWriteProvider<T> : ReadOnlyProvider<T>, WriteOnlyProvider<T>
package provider
internal class TransientProviderImpl<T>(
private val factory: InstanceFactory<T>,
) : ReadOnlyProvider<T> {
override fun get(): T = factory.invoke()
}
package provider
internal typealias OnClearListener = () -> Unit
internal typealias InstanceFactory<T> = () -> T
package provider
import kotlin.reflect.KProperty
public interface WriteOnlyProvider<T> {
public fun set(value: T)
}
/**
* Permits property delegation of `var`s using `by` for [WriteOnlyProvider].
*/
@Suppress("NOTHING_TO_INLINE")
public inline operator fun <T> WriteOnlyProvider<T>.setValue(thisObj: Any?, property: KProperty<*>, value: T) {
set(value)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment