+
Skip to content

zhgzhg/TinyDI

Repository files navigation

TinyDI

Build Status Coverage

Minimalistic, annotation-based Java library for dependency injection. Compatible with the traditional JVM, Android, GraalVM, etc.

Features

  • Constructor-based dependency injection
  • Singleton, and prototype DI scopes
  • Bean akin components which can register, or be injected with components
  • Ability to do classpath scanning of the eligible for DI components
  • Support for programmatic registration of additional components
  • Runtime or build time component scanning, allowing DI on platforms with limited reflection capabilities (Android, GraalVM native images, etc.)
  • Simple to learn and use

TinyDI - Usage Example

package tinydi.helloworld;

import com.github.zhgzhg.tinydi.TinyDI;
import com.github.zhgzhg.tinydi.components.*;
import com.github.zhgzhg.tinydi.meta.annotations.*;
import com.github.zhgzhg.tinydi.meta.enums.ScopeDI;
import java.util.Date;

/** Component responsible for the initialization of other core for the app components. */
@Registrar
class Config {

  /** A singleton component called 'appVersion' which is a string */
  @Recorded
  String appVersion() { return "1.0.0"; }
  
  /** A prototype component called 'currentTime' */
  @Recorded(value = "currentTime", scope = ScopeDI.PROTOTYPE)
  Date currDate() { return new Date(); }
}


/** Interface contract for printing an app's version and current date */
interface Informer {
  void printInfo();
}

/** A component which will be injected with the 'Recorded' component instances or possibly other 'Supervised' ones. */
@Supervised
class AppInfo implements Informer {
  private String version;
  private Date currDt;
  
  /**
   * Constructor which will be called automatically by TinyDI. If several eligible for injection
   * parameters of the same data type exist the @KnownAs annotation can be used to specify a concrete one.
   * @param appVersion Will be injected, taken from the Config class.
   * @param ct Will be injected, taken from the Config class. The KnownAs annotation is not mandatory in
   *           this example, but it's there for demonstration purposes. 
   */
  public AppInfo(String appVersion, @KnownAs("currentTime") Date ct) { 
    this.version = appVersion;
    this.currDt = ct;
  }
  
  @Override
  public void printInfo() {
    System.out.printf("App (%s) - v%s%n", this.currDt, version);
  }
}

/** The entrypoint of the Java app, and also in this example of the dependency injected app too. */
@Supervised
public class Main implements EntryPoint {

  public static void main(String[] args) {

    TinyDI.config()
      .basePackages(Main.class.getPackageName())
      .configure()
      .run();
  }
  
  
  private Informer informer;

  public Main(Informer informer) {
    this.informer = informer;
  }
  
  /** The entry point of the DI-ed app when everything is initialised */
  @Override
  public void run() {
    this.informer.printInfo();
  }
}

Limitations

  • Only dependency injection via constructor is supported
    • You may use Lombok to reduce the boilerplate code
  • Primitive types are always converted to their wrappers (for e.g. int -> Integer, long -> Long, etc...)
  • Nulls are not considered valid dependency injection values and will be ignored by the library
  • Android and GraalVM native images require serialization of the component scanning to be saved at build time

Further Reading

Consult with the wiki and the API documentation for more information.

About

Annotation-based dependency injection library for Java

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors 2

  •  
  •  

Languages

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载