Add the dependency below to your module's build.gradle.kts file:
| Module | Version |
|---|---|
| leviathan | |
| leviathan-compose |
sourceSets {
commonMain.dependencies {
// core library
implementation("io.github.composegears:leviathan:$version")
// Compose integration
implementation("io.github.composegears:leviathan-compose:$version")
}
}Use same dependencies in the dependencies { ... } section
Create Module (recommend to use object) and implement Leviathan marker interface.
Create fields using these functions:
- Use
by instanceOf { value }to create a scoped instance dependency- the instance is shared while it belongs to at least one active scope
- when the last scope closes, the instance is destroyed
- Use
by factoryOf(cacheInScope){ ... }to create factory dependencycacheInScope = true(default): caches instances within the same scopescacheInScope = false: creates new instance on each access
- Use
by singleton { value }to create a constant dependency - Use
by mutableOf { value }to create a mutable provider dependency
Declare your dependencies
class SampleRepository()
class SampleRepositoryWithParam(val param: Int)
class SampleRepositoryWithDependency(val dependency: SampleRepository)
interface SampleInterfaceRepo
class SampleInterfaceRepoImpl : SampleInterfaceRepoCreate module
// implicit DSL
object Module {
val scopedRepository by Leviathan.instanceOf { SampleRepository() }
val repositoryWithParam by Leviathan.factoryOf { SampleRepositoryWithParam(1) }
val repositoryWithDependency by Leviathan.instanceOf {
// dependency injection from the same module
SampleRepositoryWithDependency(inject(scopedRepository))
}
// interface binding
val interfaceRepo by Leviathan.instanceOf<SampleInterfaceRepo> { SampleInterfaceRepoImpl() }
val constantValue by Leviathan.singleton { 42 }
val mutableProvider by Leviathan.mutableOf { 53 }
}
// explicit DSL
class ModuleWithImplicitDsl : Leviathan {
val scopedRepository by instanceOf { SampleRepository() }
val repositoryWithDependency by instanceOf {
SampleRepositoryWithDependency(inject(scopedRepository))
}
}
// top-level
val appWideRepository by Leviathan.instanceOf { SampleRepository() }Dependencies usage:
// view model
class SomeVM(
dep1: Dependency<SampleRepository> = Module.scopedRepository,
) : ViewModel() {
val dep1value = inject(dep1)
fun foo(){
val dep2 = inject(Module.interfaceRepo)
}
}
// compose
@Composable
fun ComposeWithDI() {
val repo1 = inject(Module.scopedRepository)
val repo2 = inject { Module.repositoryWithParam }
/*..*/
}
// random access
fun foo() {
val scope = DIScope()
val repo1 = Module.scopedRepository.injectedIn(scope)
val repo2 = appWideRepository.injectedIn(scope)
// update mutable values
Module.mutableProvider.provides { 21 }
/*..*/
scope.close()
}Before:
object Module : Leviathan() {
val repo by instanceOf { SampleRepository() }
val config by mutableOf { 1 }
}After:
class ModuleWithDsl : Leviathan {
val repo by instanceOf { SampleRepository() }
val config by mutableOf { 1 }
}
// or
object Module {
val repo by Leviathan.instanceOf { SampleRepository() }
val config by Leviathan.mutableOf { 1 }
}Thank you for your help! ❤️
Developed by ComposeGears 2024
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.