Giter Club home page Giter Club logo

waltid-servicematrix's Introduction

ServiceMatrix, by walt.id

Interchange service-implementation & service-configuration at runtime (using dynamic dependency injection), for Kotlin.

All the services, the implementations, the configurations, etc. are typesafe, as all things should be.

As of commit ff82ae5: 100% test coverage according to the JaCoCo coverage report.

Maintainer: @KBurgmann

Quickstart

Setup

Add the dependency using Gradle:

implementation("id.walt.servicematrix:waltid-servicematrix:1.1.0")

or Maven:

<dependency>
    <groupId>id.walt.servicematrix</groupId>
    <artifactId>waltid-servicematrix</artifactId>
    <version>1.1.0</version>
</dependency>

Create your first service

abstract class SimpleTestService : BaseService() {
    override val implementation get() = serviceImplementation<SimpleTestService>()

    open fun function1(): Int = implementation.function1()
    open fun function2(): String = implementation.function2()

    companion object : ServiceProvider {
        override fun getService() = object : SimpleTestService() {}
    }
}

Create your first service implementation

class SimpleTestServiceImpl1 : SimpleTestService() {
    override fun function1() = 1
    override fun function2() = "Impl 1"
}

Implementations can be inherited from implementations too!

class InheritedFromImpl1 : SimpleTestServiceImpl1() {
    override fun function2() = "The better ${super.function2()}"
}

Inject them at runtime!

Using code:

ServiceRegistry.registerService<SimpleTestService>(SimpleTestServiceImpl1())

Or using a service-matrix file:

# service-matrix.properties
ServiceMatrixTestService=ServiceMatrixTestServiceImpl1
// Load "service-matrix.properties"
ServiceMatrix("service-matrix.properties")

Define a default implementation in code

Without needing any config file! (extremely useful when using your software as a dependency)

abstract class SimpleTestService : BaseService() {
override val implementation get() = serviceImplementation<SimpleTestService>()

    open fun function1(): Int = implementation.function1()
    open fun function2(): String = implementation.function2()

    companion object : ServiceProvider {
        override fun getService() = object : SimpleTestService() {}
        override fun defaultImplementation() = SimpleTestServiceImpl1()
    }
}

Want your implementation to have configuration too?

Your new service implementation:

class ConfigurationTestServiceImpl1(configurationPath: String) : ConfigurationTestService() {
    data class SomeExtraThings(val name: String)
    data class MyConfig1(val env: String, val someExtraThings: SomeExtraThings) : ServiceConfiguration

    override val configuration: MyConfig1 = fromConfiguration(configurationPath)

    override fun someInfoText(): String = configuration.someExtraThings.name
}

And the matching config file:

env: "staging"
        
someExtraThings: {
    name: "Implementation Nr. 1"
}

And then register them with code:

ServiceRegistry.registerService<SimpleTestService>(SimpleTestServiceImpl1("myConfig.conf"))

Or using a service-matrix file:

# service-matrix.properties
ServiceMatrixTestService=ServiceMatrixTestServiceImpl1:myConfig.conf
// Load "service-matrix.properties"
ServiceMatrix("service-matrix.properties")

At-runtime reconfiguration

For the following service:

abstract class ReregistrationTestService : BaseService() {
    override val implementation get() = serviceImplementation<ReregistrationTestService>()

    open fun function1(): Int = implementation.function1()

    companion object : ServiceProvider {
        override fun getService() = object : ReregistrationTestService() {}
    }
}

class ReregistrationTestServiceImpl1 : ReregistrationTestService() {
    override fun function1() = 1
}

class ReregistrationTestServiceImpl2 : ReregistrationTestService() {
    override fun function1() = 2
}

The output will be:

// Register implementation 1
ServiceRegistry.registerService<ReregistrationTestService>(ReregistrationTestServiceImpl1())

val service = ReregistrationTestService.getService()

println(service.function1()) // 1

// Reregister with implementation 2
ServiceRegistry.registerService<ReregistrationTestService>(ReregistrationTestServiceImpl2())

// Still calling the same variable!
println(service.function1()) // 2

License

The Service Matrix project by walt.id is Open Source software released under the Apache 2.0 license.

waltid-servicematrix's People

Contributors

waltkb avatar github-actions[bot] avatar philpotisk avatar kburgmann avatar

Watchers

James Cloos 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.