Skip to content

ComposeGears/Leviathan

Repository files navigation

Leviathan

Service locator implementation of DI pattern

API

Add the dependency below to your module's build.gradle.kts file:

Android / jvm

dependencies {
   implementation("io.github.composegears:leviathan:$version")
}

Multiplatform

sourceSets {
    commonMain.dependencies {
        implementation("io.github.composegears:leviathan:$version")
    }
}

Base usage

Create Module (recommend to use object) and extends from Leviathan class

Create fields using one of 2 functions:

  • Use by instance to create single-object-delegate (same instance upon every access)
  • Use by factory to create factory-delegate (new instance upon each access)

Use by (instance|factory)<Interface>{InterfaceImpl} to hide impl class

Simple case

Declare you repositories

class SampleRepository()
class SampleRepositoryWithParam(val param: Int)
class SampleRepositoryWithDependency(val dependency: SampleRepository)

interface SampleInterfaceRepo
class SampleInterfaceRepoImpl : SampleInterfaceRepo

Create module

class Module : Leviathan() {
    val lazyRepository by instance(::SampleRepository)
    val nonLazyRepository by instance(false, ::SampleRepository)
    val repositoryWithParam by factory { SampleRepositoryWithParam(1) }
    val repositoryWithDependency by instance { SampleRepositoryWithDependency(lazyRepository) }
    val interfaceRepo by instance<SampleInterfaceRepo>(::SampleInterfaceRepoImpl)
}

Dependencies usage:

fun foo() {
    val repo = Module.lazyRepository
    //...  
}

class Model(
    val repo: SampleRepository = Module.lazyRepository
) {
    //...
}

class Model() {
    private val repo = Module.lazyRepository
    //...
}

Mutli-module case

  • HttpClient
  • WeatherRepository <- HttpClient
  • NewsRepository <- HttpClient
  • App <- WeatherRepository, NewsRepository
  1. Http Client Module
    class HttpClient {
        // ...
    }
  2. Weather service module
    class WeatherRepository(client: HttpClient) {
        // ...
    }
  3. News service module
    class NewsRepository(client: HttpClient) {
       // ...
    }
  4. App service module
    object AppModule : Leviathan() {
        private val httpClient by instance { HttpClient() }
        val weatherRepository by instance { WeatherRepository(httpClient) }
        val newsRepository by instance { NewRepository(httpClient) }
    }

Advanced case

In order to create good & testable classes recommend to use advanced scenario

  1. declare dependencies
    class DataRepository //...
    class ApiRepository //...
  2. declare module interface (data/domain modules)
    interface DataModule {
        val dataRepository: DataRepository
    }
    
    interface ApiModule {
        val apiRepository: ApiRepository
    }    
  3. Create AppModule and inherit from interfaces(step #2) and Leviathan
    object AppModule : DataModule, ApiModule, Leviathan() {
        override val dataRepository: DataRepository by instance(::DataRepository)
        override val apiRepository: ApiRepository by instance(::ApiRepository)
    }
  4. Create Models (or any other classes) base on interfaces from step #2
    class Model(apiModule: ApiModule = AppModule){
        val api = apiModule.apiRepository
    
        fun foo(){/*...*/}
    }

Now you can make tests and have easy way to mock your data:

@Test
fun ModelTests(){
    val model = Model(object : ApiModule {
        override val apiRepository: ApiRepository
            get() = ApiRepository() // mock
    })
    model.foo()
}

License

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.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Languages