DependencyProperty is a dependency resolution library by Delegated Property.

Overview

DependencyProperty

DependencyProperty is a dependency resolution library by Delegated Property.

Overview

DependencyProperty is

  • simple in defining and resolving dependencies.
  • usable in classes accessible to Application instance like Activity, Fragment, and etc.
  • able to inject to ViewModel's constructor without affecting other classes.
  • less code for testing than Dagger Hilt.
  • easy to use in multi-module and Dynamic Feature Module.
  • easy to manage modules lifecycle.
  • faster build time than Dagger.
  • faster execution time than Dagger and Koin.

Usage

Configure DependencyProperty in Application

Application class must implements DependencyModulesHolder like the following.

class App: Application(), DependencyModulesHolder {
    override val dependencyModules: DependencyModules by dependencyModules(AppModule(this), CoroutinesModule())
}

You can pass DependencyModule to dependencyModules() as variadic arguments.

Define dependencies in DependencyModule

DependencyModule is marker interface. You can define dependencies as property or function.

open class CoroutinesModule : DependencyModule {
    open val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
    open val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
    open val mainDispatcher: CoroutineDispatcher = Dispatchers.Main
    open val mainImmediateDispatcher: CoroutineDispatcher = Dispatchers.Main.immediate
}

You can resolve other DependencyModule using the following extension methods.

  • inline fun Application.dependencyModule(): T
  • inline fun FragmentActivity.dependencyModule(): T
  • inline fun Fragment.dependencyModule(): T
  • inline fun AndroidViewModel.dependencyModule(): T
  • inline fun Service.dependencyModule(): T
  • inline fun Context.dependencyModule(): T
class AppModule(private val application: Application) : DependencyModule {
    private val coroutinesModule: CoroutinesModule by lazy {
        application.dependencyModule<CoroutinesModule>()
    }
    val loadItemsUseCase: LoadItemsUseCase
        get() = LoadItemsUseCase(coroutineModule.ioDispatcher)
}
  • If You want to define dependency as singleton, you can use lazy.
  • If You want to define dependency as not singleton, you can use getter.
  • If You want to define dependency using parameters, you can use function.

Resolve dependencies

You can resolve dependency by delegated property using the following extension methods.

  • fun Application.dependency (resolve: (T) -> R): Lazy
  • fun FragmentActivity.dependency (resolve: (T) -> R): Lazy
  • fun Fragment.dependency (resolve: (T) -> R): Lazy
  • fun AndroidViewModel.dependency (resolve: (T) -> R): Lazy
  • fun Service.dependency (resolve: (T) -> R): Lazy
  • fun Context.dependency (resolve: (T) -> R): Lazy

Activity's example is the following.

class MainActivity : AppCompatActivity() {
    private val loadItemsUseCase by dependency<AppModule, LoadItemsUseCase> { it.loadItemsUseCase }
}

Another example is the following.

class MainActivity : AppCompatActivity() {
    private val loadItemsUseCase: LoadItemsUseCase by lazy { dependencyModule<AppModule>().loadItemsUseCase }
}

For testing, ViewModel inherits AndroidViewModel and its constructor is annotated @JvmOverloads.

class MainViewModel @JvmOverloads constructor(
    application: Application,
    savedStateHandle: SavedStateHandle
    private val loadItemsUseCase: LoadItemsUseCase = application.dependencyModule<AppModule>().loadItemsUseCase
) : AndroidViewModel(application) {
    // You can use loadItemsUseCase
}

By @JvmOverloads, ViewModel's dependencies is passed as default arguments.

Unit Test

In Unit Test, DependencyProperty is not used. You can inject to constructor.

@Test
fun test() {
    // init loadItemsUseCase
    // ...
    // init ViewModel
    val viewModel = MainViewModel(Application(), SavedStateHandle(), loadItemsUseCase)
    // test ViewModel
}

UI Test

You need only to define CustomTestRunner and Application for testing.

android {
    defaultConfig {
        // Replace com.example with your class path.
        testInstrumentationRunner "com.example.CustomTestRunner"
    }
}
class CustomTestRunner : AndroidJUnitRunner() {
    override fun newApplication(cl: ClassLoader?, name: String?, context: Context?): Application {
        return super.newApplication(cl, TestApp::class.java.name, context)
    }
}

You can override DependencyModule by passing inherited DependencyModule.

class TestApp: Application(), DependencyModulesHolder {
    override val dependencyModules: DependencyModules by dependencyModules(AppModule(this), TestCoroutinesModule())
}

TestCoroutinesModule inherits CoroutinesModule and overrides its properties.

class TestCoroutinesModule : CoroutinesModule() {
    override val defaultDispatcher: CoroutineDispatcher = AsyncTask.THREAD_POOL_EXECUTOR.asCoroutineDispatcher()
    override val ioDispatcher: CoroutineDispatcher = AsyncTask.THREAD_POOL_EXECUTOR.asCoroutineDispatcher()
    override val mainDispatcher: CoroutineDispatcher = Dispatchers.Main
    override val mainImmediateDispatcher: CoroutineDispatcher = Dispatchers.Main.immediate
}

Multi-module and Dynamic Feature Module

In multi-module, no extra settings. You can use other module's DependencyModule in app module.

class App: Application(), DependencyModulesHolder {
    override val dependencyModules: DependencyModules by dependencyModules(AppModule(this), CoroutinesModule())
}

In Dynamic Feature Module, you can add DependencyModule dynamically using the following extension methods.

val Application.dependencyModules: DependencyModules
    get() = (this as DependencyModulesHolder).dependencyModules
val FragmentActivity.dependencyModules: DependencyModules
    get() = application.dependencyModules
val Fragment.dependencyModules: DependencyModules
    get() = requireActivity().application.dependencyModules
val AndroidViewModel.dependencyModules: DependencyModules
    get() = getApplication<Application>().dependencyModules
val Service.dependencyModules: DependencyModules
    get() = application.dependencyModules
val Context.dependencyModules: DependencyModules
    get() = (applicationContext as Application).dependencyModules

Activity's example is the following.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        dependencyModules.addModule(DynamicModule()) // add only once
    }
}

Lifecycle of DependencyModule

You can manage lifecycle of DependencyModule using the following methods.

  • fun DependencyModules.addModule(module: T)
  • fun DependencyModules.removeModule ()
  • fun DependencyModules.replaceModule(module: T)

Activity's example is the following.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Replace an existing DependencyModule of the same type with a new DependencyModule
        dependencyModules.replaceModule(AppModule(application))
    }
}

Gradle

repositories {
    maven { url "https://www.jitpack.io" }
}

dependencies {
    implementation 'com.github.wada811:DependencyProperty:x.y.z'
}

License

Copyright (C) 2020 wada811

Licensed under the Apache License, Version 2.0

You might also like...
A SharedPreference "injection" library for Android

PreferenceBinder A SharedPreferences binding library for Android. Using annotation processing, this library makes it easy to load SharedPreferences va

Easy lightweight SharedPreferences library for Android in Kotlin using delegated properties
Easy lightweight SharedPreferences library for Android in Kotlin using delegated properties

Easy lightweight SharedPreferences library for Android in Kotlin using delegated properties Idea Delegated properties in Kotlin allow you to execute a

A property/method accessor library for the JVM, written in Kotlin

unlok - unlock your JVM a property/method accessor library for the JVM, written in Kotlin. how to import you can import unlok from maven central just

Record full-resolution video on your Android devices.
Record full-resolution video on your Android devices.

DEPRECATED: Android 11 now includes native screen recording! License Copyright 2015 Jake Wharton Licensed under the Apache License, Version 2.0 (the

Quick photo and video camera with a flash, customizable resolution and no ads.
Quick photo and video camera with a flash, customizable resolution and no ads.

Simple Camera A camera with flash, zoom and no ads. The camera is usable for both photo taking and video recording. You can switch between front and r

Quick photo and video camera with a flash, customizable resolution and no ads.
Quick photo and video camera with a flash, customizable resolution and no ads.

Simple Camera A camera with flash, zoom and no ads. The camera is usable for both photo taking and video recording. You can switch between front and r

Gradle Plugin to enable auto-completion and symbol resolution for all Kotlin/Native platforms.
Gradle Plugin to enable auto-completion and symbol resolution for all Kotlin/Native platforms.

CompleteKotlin Gradle Plugin to enable auto-completion and symbol resolution for all Kotlin/Native platforms. What this plugin provides This zero-conf

Quick photo and video camera with a flash, customizable resolution and no ads.
Quick photo and video camera with a flash, customizable resolution and no ads.

Simple Camera A camera with flash, zoom and no ads. The camera is usable for both photo taking and video recording. You can switch between front and r

Pixel Boom is a Java-based Android software, featuring image super-resolution and colorization

Pixel Boom is a Java-based Android software, featuring image super-resolution and colorization.

Maxibon kata for Kotlin Developers. The main goal is to practice property based testing.
Maxibon kata for Kotlin Developers. The main goal is to practice property based testing.

Kata Maxibon for Kotlin. We are here to practice property based testing. We are going to use KotlinTest to write our tests. We are going to practice p

Maxibon kata for Kotlin Developers. The main goal is to practice property based testing.
Maxibon kata for Kotlin Developers. The main goal is to practice property based testing.

Kata Maxibon for Kotlin. We are here to practice property based testing. We are going to use KotlinTest to write our tests. We are going to practice p

Powerful, elegant and flexible test framework for Kotlin with additional assertions, property testing and data driven testing
Powerful, elegant and flexible test framework for Kotlin with additional assertions, property testing and data driven testing

Kotest is a flexible and comprehensive testing tool for Kotlin with multiplatform support. To learn more about Kotest, visit kotest.io or see our quic

😴 Lazy and fluent syntactic sugar of Kotlin for initializing Android lifecycle-aware property.
😴 Lazy and fluent syntactic sugar of Kotlin for initializing Android lifecycle-aware property.

😴 Lazy and fluent syntactic sugar of Kotlin for initializing Android lifecycle-aware property.

Backing property explained - youtube video link in documnetation
Backing property explained - youtube video link in documnetation

backing property = Kotlin = Getter Setter and Backing Property Screenshot Inside android studio open a file press Alt+Shift+A and search for kotlin

Example project for using the Selenium toolkit with Kotlin, Maven, TestNg and the config is managed via a property file.

Selenium-Java-Toolkit-TestNg-Playground This is the sample-Project and show you how to use the Selenium-Toolkit. The Selenium-Toolkit is a Java based

Kotest property test arbs for kotlinx.datetime

kotest-property-datetime Kotest property arbs for kotlinx.datetime See docs. Please create issues on the main kotest board. Changelog 1.0.0 Updated da

Kotlin compiler plugin that allows class delegation to be dynamic like property delegations

kotlin-dynamic-delegation Kotlin compiler plugin that allows class delegation to be dynamic like property delegations. The plugin is working in progre

A scope tree based Dependency Injection (DI) library for Java / Kotlin / Android.
A scope tree based Dependency Injection (DI) library for Java / Kotlin / Android.

Toothpick (a.k.a T.P. like a teepee) Visit TP wiki ! What is Toothpick ? Toothpick is a scope tree based Dependency Injection (DI) library for Java. I

Lightweight, minimalistic dependency injection library for Kotlin & Android

‼️ This project is in maintenance mode and not actively developed anymore. For more information read this statement. ‼️ Katana Katana is a lightweight

Comments
  • Dependency Dashboard

    Dependency Dashboard

    This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

    This repository currently has no open or pending branches.

    Detected dependencies

    github-actions
    .github/workflows/maven-publish.yml
    • actions/checkout v3
    • actions/setup-java v3
    gradle
    gradle.properties
    publish-module.gradle
    publish-root.gradle
    settings.gradle
    build.gradle
    • com.android.application 7.3.1
    • com.android.library 7.3.1
    • com.diffplug.spotless 6.12.0
    • org.jetbrains.kotlin.android 1.8.0
    • io.github.gradle-nexus.publish-plugin 1.1.0
    DependencyProperty/build.gradle
    • org.jetbrains.kotlin:kotlin-stdlib-jdk7 1.8.0
    • androidx.fragment:fragment-ktx 1.5.5
    • androidx.work:work-runtime 2.7.1
    gradle-wrapper
    gradle/wrapper/gradle-wrapper.properties
    • gradle 7.6

    • [ ] Check this box to trigger a request for Renovate to run again on this repository
    opened by renovate[bot] 0
Releases(2.0.0)
Owner
wada811
Android Application Architect
wada811
Lightweight, minimalistic dependency injection library for Kotlin & Android

‼️ This project is in maintenance mode and not actively developed anymore. For more information read this statement. ‼️ Katana Katana is a lightweight

REWE Digital GmbH 179 Nov 27, 2022
A fast dependency injector for Android and Java.

Dagger A fast dependency injector for Java and Android. Dagger is a compile-time framework for dependency injection. It uses no reflection or runtime

Google 16.9k Jan 5, 2023
A fast dependency injector for Android and Java.

Dagger 1 A fast dependency injector for Android and Java. Deprecated – Please upgrade to Dagger 2 Square's Dagger 1.x is deprecated in favor of Google

Square 7.3k Jan 5, 2023
Guice (pronounced 'juice') is a lightweight dependency injection framework for Java 6 and above, brought to you by Google.

Guice Latest release: 5.0.1 Documentation: User Guide, 5.0.1 javadocs, Latest javadocs Continuous Integration: Mailing Lists: User Mailing List Licens

Google 11.7k Jan 1, 2023
:syringe: Transfuse - A Dependency Injection and Integration framework for Google Android

Transfuse Transfuse is a Java Dependency Injection (DI) and integration library geared specifically for the Google Android API. There are several key

John Ericksen 224 Nov 28, 2022
Painless Kotlin Dependency Injection

KOtlin DEpendency INjection Kodein-DI is a very simple and yet very useful dependency retrieval container. it is very easy to use and configure. Kodei

null 2.9k Jan 1, 2023
Koin - a pragmatic lightweight dependency injection framework for Kotlin

What is KOIN? - https://insert-koin.io A pragmatic lightweight dependency injection framework for Kotlin developers. Koin is a DSL, a light container

insert-koin.io 7.8k Jan 8, 2023
The dependency injection Dagger basics and the concepts are demonstrated in different branches

In this project we will look at the dependency injection Dagger basics and the concepts are demonstrated in different branches What is an Dependency?

Lloyd Dcosta 6 Dec 16, 2021
Simple Android Library, that provides easy way to start the Activities with arguments.

Warning: Library is not maintained anymore. If you want to take care of this library, propose it via Pull Request. It needs adjustmensts for newer ver

Marcin Moskała 429 Dec 15, 2022
A multi-purpose library containing view injection and threading for Android using annotations

SwissKnife A multi-purpose Groovy library containing view injection and threading for Android using annotations. It's based on both ButterKnife and An

Jorge Martin Espinosa 251 Nov 25, 2022