https://github.com/chrynan/locator

A Service Locator Library for Kotlin Multi-platform

https://github.com/chrynan/locator

Science Score: 26.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (6.5%) to scientific vocabulary

Keywords

dependency-injection kotlin kotlin-library kotlin-multi-platform kotlin-multiplatform service-locator

Keywords from Contributors

federated parcel
Last synced: 5 months ago · JSON representation

Repository

A Service Locator Library for Kotlin Multi-platform

Basic Info
  • Host: GitHub
  • Owner: chRyNaN
  • License: apache-2.0
  • Language: Kotlin
  • Default Branch: master
  • Homepage:
  • Size: 73.2 KB
Statistics
  • Stars: 2
  • Watchers: 1
  • Forks: 1
  • Open Issues: 0
  • Releases: 0
Topics
dependency-injection kotlin kotlin-library kotlin-multi-platform kotlin-multiplatform service-locator
Created over 6 years ago · Last pushed over 4 years ago
Metadata Files
Readme License

README.md

locator

A very simple Service Locator Library for Kotlin Multiplatform

Using the library

  • Create a custom Module Interface extending from the Module interface ```kotlin interface ScreenModule : Module {

    val presenter: ScreenPresenter

    val navigator: ScreenNavigator } ```

  • Create the Module Implementation ```kotlin class ScreenModuleImpl(view: ScreenView) : ScreenModule {

    override val presenter: ScreenPresenter = ScreenPresenter(view = view)

    override val navigator: ScreenNavigator = ScreenNavigator(view = view) } ```

  • Implement the LocatesWith interface ```kotlin class Screen : BaseScreen(), ScreenView, LocatesWith {

    override val module: ScreenModule = ScreenModuleImpl(view = this)

    ... } ```

  • Access values provided by the Module: ```kotlin class Screen : BaseScreen(), ScreenView, LocatesWith {

    override val module: ScreenModule = ScreenModuleImpl(view = this)

    private val presenter: ScreenPresenter by locate { presenter }

    private val navigator: ScreenNavigator? by locateOrNull { navigator }

    override fun onCreate() { attachToDependencyGraph() // Could also access the fields by the module property module.presenter }

    override fun onDestroy() { detachFromDependencyGraph() } } ```

Customization

The Modules can contain any fields or functions that are accessible in the locate or locateOrNull delegates. This is due to the delegates being scoped to the Module. ```kotlin class MyModule(private val myView: ScreenView) : Module {

val fieldAssignedOnce: String = "Field Assigned Once"

val nullableField: String? = null

val lazyField: String by lazy { "Lazy Field" }

val getterField: String
  get() = "Getter Field"

val presenter: MyPresenter = MyPresenter(view = myView)

fun otherPresenter(otherView: ScreenView) = MyPresenter(view = otherView)

}

class Screen : BaseScreen(), ScreenView, LocatesWith {

override val module: MyModule = MyModule(view = this)

val fieldAssignedOnce by locate { fieldAssignedOnce }

val nullableField by locate { nullableField }

internal val lazyField by locate { lazyField }

private val getterField by locate { getterField }

private val presenter by locate { presenter }

private val otherPresenter by locate { otherPresenter(otherView = this) } } ```

Delegates

  • The locate function can return a type (nullable or non-nullable) if the field is present. Meaning that the module is defined. Otherwise an exception will be thrown. The exception thrown could either be a ModuleNotInitializedException or a ModuleClassCastException.

  • The locateOrNull acts just like the locate function but returns null instead of throwing an exception.

Dependency Graph Building

You create the Dependency Graph using inheritance with the Modules.

Consider the following Module that lives as long as the Application is running: ```kotlin interface WebModule : Module {

val baseUrl: String

}

class WebModuleImpl : WebModule {

override val baseUrl: String = "https://chrynan.com"

}

class Application : BaseApplication(), LocatesWith {

override val module: WebModule = WebModuleImpl()

override fun onCreate() {
    attachToDependencyGraph()
}

override fun onDestroy() {
    detachFromDependencyGraph()
}

} ```

Then a Module that depends on the above Module, may look like this: ```kotlin interface ScreenModule : Module, WebModule {

val presenter: ScreenPresenter

val navigator: ScreenNavigator

}

class ScreenModuleImpl(view: ScreenView) : ScreenModule, WebModule by dependencyGraph() {

override val presenter: ScreenPresenter = ScreenPresenter(view = view, baseUrl = baseUrl)

override val navigator: ScreenNavigator = ScreenNavigator(view = view)

}

class Screen : BaseScreen(), ScreenView, LocatesWith {

override val module: ScreenModule = ScreenModuleImpl(view = this)

private val presenter: ScreenPresenter by locate { presenter }

private val navigator: ScreenNavigator? by locateOrNull { navigator }

override fun onCreate() {
    attachToDependencyGraph()
    // Could also access the fields by the module property
    module.presenter
}

override fun onDestroy() {
    detachFromDependencyGraph()
}

} ```

The dependencyGraph() function looks for the correct Module type through the currently attached modules. If it isn't present it will fail and the application will crash. Alternatively, you could explicitly provide the module: ```kotlin interface ScreenModule : Module, WebModule {

val presenter: ScreenPresenter

val navigator: ScreenNavigator

}

class ScreenModuleImpl( webModule: WebModule, view: ScreenView ) : ScreenModule, WebModule by webModule {

override val presenter: ScreenPresenter = ScreenPresenter(view = view, baseUrl = baseUrl)

override val navigator: ScreenNavigator = ScreenNavigator(view = view)

} ```

Building the library

The library is provided through Bintray. Refer to the releases page for the latest version.

Repository

kotlin repositories { maven { url = uri("https://dl.bintray.com/chrynan/chrynan") } }

Dependencies

Kotlin Common Core Module: kotlin implementation("com.chrynan.locator:locator-core:$VERSION")

Kotlin JVM Module: kotlin implementation("com.chrynan.locator:locator-core-jvm:$VERSION")

Kotlin JS Module: kotlin implementation("com.chrynan.locator:locator-core-js:$VERSION")

Owner

  • Name: Christopher
  • Login: chRyNaN
  • Kind: user
  • Location: Austin, TX
  • Company: Starry

GitHub Events

Total
Last Year

Committers

Last synced: 7 months ago

All Time
  • Total Commits: 6
  • Total Committers: 2
  • Avg Commits per committer: 3.0
  • Development Distribution Score (DDS): 0.5
Past Year
  • Commits: 0
  • Committers: 0
  • Avg Commits per committer: 0.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
Christopher b****p@g****m 3
Chris c****n@s****m 3
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 7 months ago


Dependencies

.github/workflows/build.yml actions
  • actions/checkout v1 composite
  • actions/setup-java v1 composite
.github/workflows/greetings.yml actions
  • actions/first-interaction v1 composite
.github/workflows/publish.yml actions
  • actions/checkout v1 composite
  • actions/setup-java v1 composite
build.gradle maven
  • org.jetbrains.kotlin:kotlin-stdlib-common * implementation
  • org.jetbrains.kotlin:kotlin-stdlib-jdk8 * implementation
  • org.jetbrains.kotlin:kotlin-stdlib-js * implementation