Kotlin DI fast and safe library
This library fit to small and espesially huge projects. You can use it for multimodule Kotlin/Java project.
Advantages of this libraries:
- Lightweight - the entire library takes only 5 KB space
- Fast - this library doesn't use Codegen or Reflection, only your code
- Api/Core Modules - you can connect super-lightweight api module to feature libraries, and core module for main library
- Safe - unlike Dagger 2, kodin or koin you have to write all implmentation of objects, but API of this library really short
- Simple - it's probably takes less code than Dagger 2
- Lifecycle Management - there are a lot of helpers in library to mange lifecyle of components/deps set/dep
Commonly you don't have to create a lot of modules in your application, especially if you are using Gradle.
Try to create modules like a group of features. If some screen/parts are using in several modules, you can move it to common module.
Eventially your module system should looks like this.
implementation("io.github.andrewchupin:core:1.1.0")
implementation("io.github.andrewchupin:api:1.1.0")
// or with android helpers
implementation("io.github.andrewchupin:android:1.1.0")
// Dependencies
class Seed(num: Int)
class Network(seed: Seed)
// Dependency with interface
interface ServiceRepo
class ServiceRepoImpl(application: Application, net: Network) : ServiceRepo
// Feature deps
class FooData
class FooRepo(val id: FooData, val net: Network)
class FooFeature(val repo: FooRepo, val serviceRepo: ServiceRepo)
// Main Component
class AppComponent(
val service: Service,
): Component {
interface Net {
val seed: Seed
val network: Network
}
interface Service {
val net: Net
val repo: ServiceRepo
}
}
// Feature Component (have to provide something)
interface FooComponent : Component {
val service: AppComponent.Service
val repo: FooRepo
}
class AppComponentProvider(
private val application: Application
) : ComponentProvider() {
fun getFoo(id: FooData): FooComponent {
return getOrCreate(id) {
object : FooComponent {
override val service = app.service
override val repo by depRc { FooRepo(id, service.net.network) }
}
}
}
val app get() = getOrCreate {
AppComponent(
object : AppComponent.Service {
override val net = object : AppComponent.Net {
private val num = 12 // with component
override val seed by depLazy { Seed(num) } // lazy
override val network by depLazy { Network(seed) } // lazy
}
override val repo by depRc { ServiceRepoImpl(application, net.network) } // ref-counter
}
)
}
}
interface ManDelegate {
fun provideFoo(data: FooData): FooFeature
fun provideBar(data: FooData): BarFeature
}
object ModInjector : Injector<ManDelegate>()
class Application {
fun onCreate() {
Kitten.init(
provider = AppComponentProvider(this)
) { deps ->
// Create deps and component immediately
create { deps.app }
// Init delegate without deps and components
register(ModInjector) {
object : ManDelegate {
private fun component(data: FooData) = deps.getFoo(data)
override fun provideFoo(data: FooData) = FooFeature(component(data).repo, deps.app.service.repo)
override fun provideBar(data: FooData): BarFeature = BarFeature(component(data).service.repo)
}
}
}
}
}
class FooFragment : ComponentLifecycle {
// View
fun onAttach() {
val feature = ModInjector.injectWith(this) { provideFoo(FooData()) }
// or short example
val feature1 = ModInjector.inject { provideFoo(FooData()) }
// or viewModel short example
val viewModel = ModInjector.viewModelLegacy { provideBar(FooData()) }
}
// Compose
@Composable
fun Content() {
val feature = ModInjector.injectWith(this) { provideBar(FooData()) }
// or short example
val feature1 = ModInjector.inject { provideBar(FooData()) }
// or viewModel short example
val viewModel = ModInjector.viewModel { provideBar(FooData()) }
}
}