Code Monkey home page Code Monkey logo

kitten's Introduction

Kitten

Kotlin DI fast and safe library

Why?

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

How to make module system?

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. image

Guide

1. Add ":core" dependency to your Main Library (Application Entrypoint)

implementation("com.vk.kitten:core:1.0.0")

2. Add ":api" dependency to your Secondary Modules (Feature Entrypoint)

implementation("com.vk.kitten:api:1.0.0")

3. Create some dependecies

// 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)

4. Create some components in Main Module

// Main Component
class AppComponent(
    deps: Deps
): BaseComponent<AppComponent.Deps>(deps) {
    interface Deps {
        val seed: Seed
        val network: Network
        val serviceRepo: ServiceRepo
    }
}

// Feature Component (have to provide something)
class FooComponent(
    deps: Deps
) : ProviderComponent<FooComponent.Deps, FooFeature>(deps) {
    override fun provide() = FooFeature(deps.repo, deps.serviceRepo)
    
    // If component depends on another module you have to inherit it deps
    interface Deps : AppComponent.Deps {
        val repo: FooRepo
    }
}

5. Create Component Provider in Main Module

class AppComponentProvider(
    private val application: Application
) : ComponentProvider() {

    private val wrapperApp by componentWrapper<AppComponent>()
    private val wrapperFoo by componentWrapper<FooComponent>()

    fun getApp(): AppComponent {
        return wrapperApp.getOrCreate(lifecycle) {
            AppComponent(
                object : AppComponent.Deps {
                    // with component
                    private val num = 12

                    // each time new
                    override val seed by newDep { Seed(num) }

                    // first call
                    override val network by lazyDep { Network(seed) }

                    // ref-counter
                    override val serviceRepo by rcDep { ServiceRepoImpl(application, network) }
                }
            )
        }
    }

    fun getFoo(id: FooData): FooComponent {
        // you can pass key like id to componentWrapper to identify specific component
        // that means you will get different components for different keys
        // by default key is null
        return wrapperFoo.getOrCreate(lifecycle, id) {
            FooComponent(
                object : FooComponent.Deps, AppComponent.Deps by getApp().delegate() {
                    override val repo by rcDep { FooRepo(id, network) }
                }
            )
        }
    }
}

6. Create Injector in each Secondary Module

interface ManDelegate {
    fun provideFoo(data: FooData): FooFeature
    fun provideBar(data: FooData): BarFeature
}

object ModInjector : Injector<ManDelegate>()

7. Init Injector in Main Module

class Application : ComponentLifecycle {

    fun onCreate() {
        val app = this

        DependencyRegistry(
            provider = AppComponentProvider(app)
        ).apply {
            // Create deps and component immediately
            create(app, AppComponentProvider::getApp)

            // Init delegate without deps and components
            register(ModInjector) { provider ->
                object : ManDelegate {
                    override fun provideFoo(data: FooData): FooFeature {
                        return provider.getFoo(data)
                            .provide()
                    }

                    override fun provideBar(data: FooData): BarFeature {
                        return provider.getBar(data)
                            .provide()
                    }
                }
            }
        }
    }
}

8. Get your dependencies in each Secondary Module

class FooFragment : ComponentLifecycle {
    fun onAttach() {
        val feature = ModInjector.injectWith(this) { provideFoo(FooData()) }
    }
}

kitten's People

Contributors

andrewchupin avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.