Giter VIP home page Giter VIP logo

kastle's Introduction

KASTLE (ˈkæs.əl)

(Kotlin Aspect Service Transparent Locator Engine)

About

Small service locator for kotlin.

Explicit Dependency is usually better than Implicit Dependency

People should use Service Locator instead of Dependency Injection.

Example

Just call Locator.get(Class<T>), then you'll get the instance.

import com.lavans.kastle.Locator
class UserService(){
  private val userRepo = Locator.get(UserRepo::class)
  fun get(id: Int) = userRepo.find(id)
}

Replace with Mock class

You can replace instance without paying cost to learn mock library.

fun main(){
  Locator.put(UserRepo::class, MockedUserRepo::class)
  UserService().get(1) // ... MockedUserRepo.find() will be called
}

Just write mock class that you want to do.

class MockedUserRepo(): UserRepo(){
  override fun find(id: Int) = DUMMY_USER
}

Not-overrided functions are still valid since it's derived from real UserRepo.

Singleton or Prototype

Default is Singleton. If you want to use class as prototype, just add 1 parameter.

  Locator.put(Real::class, Type.Prototype)

You can set both Mock and Type at the same time.

  Locator.put(Real::class, Mocked::class, Type.Prototype)

Confirm current settings (wip)

You can see current setting like this:

log.debug(Locator.list())

Customize for Aspect (wip)

You can customize your instance dynamically with cglib.

For example, If you want to manage DB transaction from services. See below:

object TransactionalServiceLocator {
  fun <T>get(klass: Class<T>){
    if(Locator.has(klass)){
      return Locator.get(klass)
    }
    val service = createService(klass, TransactionInterceptor())
    Locator.set(klass, service)
    return (T)service
  }

  fun <T>create(klass: Class<T>, callback: Callback): T {
    val enhancer = Enhancer()
    enhancer.setSuperclass(klass)
    enhancer.setCallback(callback)
    return (T)enhancer.create()
  }
}

Implement Interceptor using cglib's MethodInterceptor

import net.sf.cglib.proxy.MethodInterceptor

class TransactionInterceptor: MethodInterceptor{
  override fun intercept(target: Any, method: Method, args: Array<Any>, proxy: MethodProxy) {
    startTransaction();
    try{
      result = proxy.invokeSuper(obj, args);
      commit();
      return result;
    }catch(e: Exception){
      rollback();
      throw e;
    }
  }
  private fun startTransaction() = // implement your db's transaction
  private fun commit() = // ...
  private fun rollback() = // ...
}

Service Locator vs DI container

Martin Fowler said:

Inversion of control is a common feature of frameworks, but it's something that comes at a price. It tends to be hard to understand and leads to problems when you are trying to debug. So on the whole I prefer to avoid it unless I need it.

https://www.martinfowler.com/articles/injection.html

It might be better to use DI in some special cases. But usually it wastes time and effort resources. ServiceLocator is simple and enough solution.


Happy Hacking!

kastle's People

Contributors

dobashi avatar

Stargazers

 avatar  avatar

Watchers

 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.