Skip to content
This repository has been archived by the owner on Oct 1, 2024. It is now read-only.

Commit

Permalink
fix: WiredModule
Browse files Browse the repository at this point in the history
  • Loading branch information
makeevrserg committed Aug 20, 2023
1 parent c23797d commit e36b740
Show file tree
Hide file tree
Showing 9 changed files with 343 additions and 106 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ That's it! As easy as it looks
## Experimental WiredModule
Dependencies can be remembered via WiredModule
```kotlin
class RootWiredModule : WiredModule by WiredModule.Default() {
val intSingle = Single { 10 }.remember()
val intProvider = Provider { 11 }.remember()
val intFactory = Factory { 13 }.remember()
val intReloadable = Reloadable { Random.nextInt() }.remember()
class RootWiredModule : WiredModule by WiredModule.wire() {
val intSingle = Single { 10 }.also(::remember)
val intProvider = Provider { 11 }.also(::remember)
val intFactory = Factory { 13 }.also(::remember)
val intReloadable = Reloadable { Random.nextInt() }.also(::remember)
}

class MySubModule(
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ makeevrserg.java.ktarget=17
# Project
makeevrserg.project.name=KDI
makeevrserg.project.group=ru.astrainteractive.klibs
makeevrserg.project.version.string=1.1.0
makeevrserg.project.version.string=1.2.0
makeevrserg.project.description=KMM library for manual DI
makeevrserg.project.developers=makeevrserg|Makeev Roman|makeevrserg@gmail.com
makeevrserg.project.url=https://github.com/makeevrserg/kdi
Expand Down
6 changes: 5 additions & 1 deletion kdi/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ kotlin {

sourceSets {
/* Main source sets */
val commonMain by getting
val commonMain by getting {
dependencies {
implementation("co.touchlab:kermit:2.0.0-RC5") // Add latest version
}
}
val nativeMain by creating
val jvmMain by getting
val androidMain by getting
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package ru.astrainteractive.klibs.kdi.wired

import co.touchlab.kermit.Logger
import ru.astrainteractive.klibs.kdi.ExperimentalKDIApi
import ru.astrainteractive.klibs.kdi.Factory
import ru.astrainteractive.klibs.kdi.Lateinit
import ru.astrainteractive.klibs.kdi.Provider
import ru.astrainteractive.klibs.kdi.Reloadable
import ru.astrainteractive.klibs.kdi.Single
import kotlin.reflect.KClass

/**
* This is default implementation of [WiredModule] which can be used with delegation
*/
@OptIn(ExperimentalKDIApi::class)
@Suppress("TooManyFunctions")
internal class DefaultWiredModule : WiredModule {

private val wires = HashSet<Wire<*>>()
private inline fun <T : Any> rememberWire(wire: Wire<T>) {
if (wires.contains(wire)) error("Factory set already contains $this")
Logger.i(tag = TAG) { "Remembered Factory $this" }
wires.add(wire)
}

override fun <T : Any> Factory<T>.remember(clazz: KClass<T>): Factory<T> {
Wire.Factory(clazz, this).run(::rememberWire)
return this
}

override fun <T : Any> Provider<T>.remember(clazz: KClass<T>): Provider<T> {
Wire.Provider(clazz, this).run(::rememberWire)
return this
}

override fun <T : Any, K : Single<T>> K.remember(clazz: KClass<T>): K {
Wire.Dependency.Single(clazz, this).run(::rememberWire)
return this
}

override fun <T : Any, K : Lateinit<T>> K.remember(clazz: KClass<T>): K {
Wire.Dependency.Lateinit(clazz, this).run(::rememberWire)
return this
}

override fun <T : Any, K : Reloadable<T>> K.remember(clazz: KClass<T>): K {
Wire.Dependency.Reloadable(clazz, this).run(::rememberWire)
return this
}

override fun <T : Any> single(kClass: KClass<T>): Single<T> {
return wires.filterIsInstance<Wire.Dependency.Single<T>>().first {
it.kClass == kClass
}.instance
}

override fun <T : Any> reloadable(kClass: KClass<T>): Reloadable<T> {
return wires.filterIsInstance<Wire.Dependency.Reloadable<T>>().first {
it.kClass == kClass
}.instance
}

override fun <T : Any> lateinit(kClass: KClass<T>): Lateinit<T> {
return wires.filterIsInstance<Wire.Dependency.Lateinit<T>>().first {
it.kClass == kClass
}.instance
}

override fun <T : Any> factory(kClass: KClass<T>): Factory<T> {
return wires.filterIsInstance<Wire.Factory<T>>().first {
it.kClass == kClass
}.instance
}

override fun <T : Any> provider(kClass: KClass<T>): Provider<T> {
return wires.filterIsInstance<Wire.Provider<T>>().first {
it.kClass == kClass
}.instance
}

companion object {
private const val TAG = "WiredModule"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package ru.astrainteractive.klibs.kdi.wired

import kotlin.reflect.KClass

internal sealed class Wire<T : Any>(val kClass: KClass<T>) {
class Factory<T : Any>(
kClass: KClass<T>,
val instance: ru.astrainteractive.klibs.kdi.Factory<T>
) : Wire<T>(kClass)

class Provider<T : Any>(
kClass: KClass<T>,
val instance: ru.astrainteractive.klibs.kdi.Provider<T>
) : Wire<T>(kClass)

sealed class Dependency<T : Any, K : ru.astrainteractive.klibs.kdi.Dependency<T>>(
kClass: KClass<T>,
val instance: K
) : Wire<T>(kClass) {
class Single<T : Any>(
kClass: KClass<T>,
instance: ru.astrainteractive.klibs.kdi.Single<T>
) : Dependency<T, ru.astrainteractive.klibs.kdi.Single<T>>(kClass, instance)

class Reloadable<T : Any>(
kClass: KClass<T>,
instance: ru.astrainteractive.klibs.kdi.Reloadable<T>
) : Dependency<T, ru.astrainteractive.klibs.kdi.Reloadable<T>>(kClass, instance)

class Lateinit<T : Any>(
kClass: KClass<T>,
instance: ru.astrainteractive.klibs.kdi.Lateinit<T>
) : Dependency<T, ru.astrainteractive.klibs.kdi.Lateinit<T>>(kClass, instance)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package ru.astrainteractive.klibs.kdi.wired

import ru.astrainteractive.klibs.kdi.ExperimentalKDIApi
import ru.astrainteractive.klibs.kdi.Factory
import ru.astrainteractive.klibs.kdi.Lateinit
import ru.astrainteractive.klibs.kdi.Provider
import ru.astrainteractive.klibs.kdi.Reloadable
import ru.astrainteractive.klibs.kdi.Single

/**
* This will remember and return current factory instance
*/
@OptIn(ExperimentalKDIApi::class)
inline fun <reified T : Any> WiredModule.remember(instance: Factory<T>): Factory<T> {
return instance.remember(T::class)
}

/**
* This will remember and return current lateinit instance
*/
@OptIn(ExperimentalKDIApi::class)
inline fun <reified T : Any> WiredModule.remember(instance: Lateinit<T>): Lateinit<T> {
return instance.remember(T::class)
}

/**
* This will remember and return current provider instance
*/
@OptIn(ExperimentalKDIApi::class)
inline fun <reified T : Any> WiredModule.remember(instance: Provider<T>): Provider<T> {
return instance.remember(T::class)
}

/**
* This will remember and return current reloadable instance
*/
@OptIn(ExperimentalKDIApi::class)
inline fun <reified T : Any> WiredModule.remember(instance: Reloadable<T>): Reloadable<T> {
return instance.remember(T::class)
}

/**
* This will remember and return current single instance
*/
@OptIn(ExperimentalKDIApi::class)
inline fun <reified T : Any> WiredModule.remember(instance: Single<T>): Single<T> {
return instance.remember(T::class)
}

/**
* This will return factory or throws [IllegalStateException] if not found
*/
@OptIn(ExperimentalKDIApi::class)
inline fun <reified T : Any> WiredModule.factory(): Factory<T> {
return factory(T::class)
}

/**
* This will return reloadable or throws [IllegalStateException] if not found
*/
@OptIn(ExperimentalKDIApi::class)
inline fun <reified T : Any> WiredModule.lateinit(): Lateinit<T> {
return lateinit(T::class)
}

/**
* This will return provider or throws [IllegalStateException] if not found
*/
@OptIn(ExperimentalKDIApi::class)
inline fun <reified T : Any> WiredModule.provider(): Provider<T> {
return provider(T::class)
}

/**
* This will return reloadable or throws [IllegalStateException] if not found
*/
@OptIn(ExperimentalKDIApi::class)
inline fun <reified T : Any> WiredModule.reloadable(): Reloadable<T> {
return reloadable(T::class)
}

/**
* This will return single or throws [IllegalStateException] if not found
*/
@OptIn(ExperimentalKDIApi::class)
inline fun <reified T : Any> WiredModule.single(): Single<T> {
return single(T::class)
}
Loading

0 comments on commit e36b740

Please sign in to comment.