Skip to content

ljacqu/DependencyInjector

Repository files navigation

Lightweight Dependency Injector

Build Status Coverage Status Javadocs Code Climate

Simple but customizable dependency injector for Java 1.8 and above.

Why use it

  • Very lightweight (only has javax.inject and javax.annotation-api as dependency)
  • Allows gradual transition to injection for existing projects
  • You can implement your own injection methods and behaviors
  • Support for projects with optional dependencies

Integrating it

Using Maven, you can get the injector by adding this to your pom.xml:

<dependency>
    <groupId>ch.jalu</groupId>
    <artifactId>injector</artifactId>
    <version>1.0</version>
</dependency>

Simple example

By default, the injector supports constructor injection and field injection. Consider the following class skeletons:

public class Settings {
  // regular class
}

public class Messages {
  private File messagesFile;

  @Inject
  Messages(Settings settings) {
    messagesFile = new File(settings.getLanguage() + ".txt");
  }
}

public class CalculationService {
  @Inject
  private Messages messages;
  
  @Inject
  private RoundingService roundingService;
}

public class RoundingService {
  private int precision;

  @Inject
  RoundingService(Settings settings) {
    precision = settings.getPrecision();
  }
}

At the startup of the application, we might only care about getting an instance of CalculationService. All other classes are required by it to run, but we don't immediately care about them. With the injector, we don't have to deal with those classes and can just retrieve what we actually want:

public class MyApp {

  public static void main(String... args) {
    Injector injector = new InjectorBuilder().addDefaultHandlers("com.example.my.project").create();
    CalculationService calcService = injector.getSingleton(CalculationService.class);
    calcService.performCalculation();
  }
}

... That's all! No need to deal with creating any other classes, but you still have a setup that allows you to easily unit test or switch a component.

--> Full, runnable example can be found here.

Handlers

You may implement your own logic to instantiate classes and resolve dependencies. This allows you, for example, to implement specific behavior for custom annotations. Read more on the Wiki: Handlers explained