SkillAgentSearch skills...

EasyDI

Easy Dependency Injection for Java

Install / Use

/learn @manuel-mauky/EasyDI
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

EasyDI - Dependency Injection for Java

Build Status

EasyDI is a small dependency injection (DI) library for java projects.

It's designed for small projects that don't need a full-blown DI-framework. To be as easy as possible EasyDI has fewer features compared to other DI frameworks and some limitations:

  • Only constructor injection is supported, no setter/field injection
  • No PostConstruct or PreDestroy
  • Uses some JSR-330 annotations (jakarta.inject.*, formerly javax.inject.*) but is not a compliant implementation of JSR-330

If you like to use dependency injection but EasyDI doesn't fit your needs you might want to try other DI frameworks like CDI, Guice or Dagger.

Links

JavaDoc 0.6.0

Maven Dependencies

EasyDI releases are available in the Maven Central Repository. You can use it like this:

Stable release

Gradle

repositories {
    mavenCentral()
}

dependencies {
    compile 'eu.lestard:easy-di:0.6.0'
}

Maven

<dependency>
    <groupId>eu.lestard</groupId>
    <artifactId>easy-di</artifactId>
    <version>0.6.0</version>
</dependency>

Current Development version (Snapshot)

The development version is published automatically to the Sonatype Snapshot repository.

Gradle

repositories {
    maven {
        url "https://oss.sonatype.org/content/repositories/snapshots/"
    }
}

dependencies {
    compile 'eu.lestard:easy-di:0.7.0-SNAPSHOT'
}

Maven

<dependency>
    <groupId>eu.lestard</groupId>
    <artifactId>easy-di</artifactId>
    <version>0.7.0-SNAPSHOT</version>
</dependency>

Tutorial

In the wiki there is a tutorial where all features of EasyDI are described. In the example we are creating a coffee machine application: wiki.

The code for this example is located in the test source directory: /src/test/java/eu/lestard/easydi/examples/coffee/

Real-World Examples:

  • SnakeFX: A Snake clone written in JavaFX
  • Nonogram: A nonogram puzzle game written in JavaFX

How to Use

1. Add the library to your project

There are two ways of using the library in your project:

  1. Use a Build-System like Gradle or Maven. EasyDI is available in the Maven Central Repository. See Maven dependencies
  2. Download the ZIP file from the github release page. The file contains the library JAR file and the JAR for javax.inject which is needed as dependency. Add both JAR files to the classpath of your project.

2. Create your classes

Write your Java classes. When your class needs an instance of another class, simply add this dependency as a constructor parameter.

public class Car {

    private final Engine engine;

    public Car(Engine engine){
        this.engine = engine;
    }

    public void drive() {
        engine.start();
        engine.accelerate();
    }
}

public class Engine {
    public void start(){
        ...
    }

    public void accelerate(){
        ...
    }
}

3. Use EasyDI to get instances of your classes

import eu.lestard.easydi.EasyDI;

public class CarApp {

    public static void main(String...args){
        EasyDI easyDI = new EasyDI();

        final Car car = easyDI.getInstance(Car.class);

        car.drive();
    }
}

For this simple use case EasyDI doesn't need any annotations or configuration.

Optional Features

Multiple Constructors

When a class has more then one public constructor, you need to tell EasyDI which one it should use. This is done with the annotation javax.inject.Inject:

public class Car {
    ...
    @Inject
    public Car(Engine engine){
        // this constructor will be used
        ...
    }

    public Car(){
        ...
    }
}

Interfaces and Implementing classes

EasyDI doesn't know which implementing class it should use when an interface type is requested as a dependency. You have to tell it with the easyDI.bindInterface(interfaceType, implementingType) method.

public interface Engine {}

public class GasolineEngine implements Engine {}

public class ElectricMotor implements Engine {}


EasyDI easyDi = new EasyDI();
easyDI.bindInterface(Engine.class, ElectricMotor.class);
...

final Engine engine = easyDI.getInstance(Engine.class);

assertThat(engine).isInstanceOf(ElectricMotor.class);

Singletons

By default EasyDI will create new instances every time a dependency is requested. If there should only be a single instance of a specific class you have to tell EasyDI. There are two ways of doing this:

1. @Singleton

The recommended way is to use the javax.inject.Singleton annotation on the class that should be a singleton:

@Singleton
public class Car {
...
}

2. EasyDI.markAsSingleton()

You can mark a class as singleton with the method markAsSingleton. This is useful when you for some reason can't modify the source code of the class (i.e. when it is part of a third-party library).

EasyDI easyDI = new EasyDI();

easyDI.markAsSingleton(ThirdParty.class);
...

Providers

If you like to inject instances of a class that doesn't meet the requirements of EasyDI you can add a javax.inject.Provider for this class. There are many use cases where this can be useful:

  • There is only a factory method to get instances of this class but no constructors
  • There is no public constructor or there are more than one public constructors and (for some reason) you can't add the @Inject annotation
  • The class is implemented with the classical Singleton design pattern.
  • You need to make some configuration on the created instance before it can be used for injection.
  • You like to use abstract classes as dependency (see next section)
EasyDI easyDI = new EasyDI();

easyDI.bindProvider(Engine.class, new Provider<Engine>() {
    @Override
    public Engine get(){
        Engine engine = new Engine();
        engine.configureThis();
        engine.configureThat();
        return engine;
    }
});

With Java 8 lambdas you would write this:

easyDI.bindProvider(Engine.class, ()-> {
    Engine engine = new Engine();
    engine.configureThis();
    engine.configureThat();
    return engine;
});

Abstract classes

If an instance of an abstract class is requested, EasyDI can't know out of the box which implementing class it should use.

This is the same situation as with interfaces. Unlike interfaces at the moment there is no explicit way of defining a binding for abstract classes. The reason is that there are far more possibilities for (miss-)configuration when it comes to (abstract) class bindings.

When you like to use abstract classes as dependencies you will have to create a provider for this class.

Lazy injection / lazy instantiation

In some use cases you need an instance of a class but at the time your constructor is called this dependency isn't available yet or it shouldn't be instantiated at this time. Instead you like to retrieve the instance at some later point in time.

Another similar use case is when you need a dependency only under some conditions and the construction of the dependency is expensive.

In both cases lazy injection is your friend. EasyDI can do lazy injection like this:

  1. change the type of the constructor parameter from T to javax.inject.Provider<T>
  2. call the method get on the provider instance when you need the actual instance

Example:


public class Car {

    private Provider<Engine> engineProvider;

    public Car(Provider<Engine> engineProvider){
        this.engineProvider = engineProvider;
    }

    public void buildCar(){
        Engine engine =  engineProvider.get();

        ...
    }

In this example the instance of the Engine is only created when the buildCar method is called. In this case the normal dependency injection mechanism of EasyDI with all configuration rules described above will run and retrieve an instance of Engine.

Recommendation: In general lazy injection should only be the last choice when you really can't inject an instance directly in the constructor. Code with lazy injection will typically be harder to reason about. It's not trivial anymore to tell at which point in time an instance of your class will be created.

Bind instances

In some use cases you like to define that one specific instance is injected every time the given type is requested. This is like a singleton configuration only that you define the exact instance on your own instead of only defining that the given type is a singleton and let EasyDI create the instance.

Engine engine = new Engine();
easyDI.bindInstance(Engine.class, engine);

This is a shortcut for this:

Engine engine = new Engine();
easyDI.bindProvider(Engine.class, () -> engine);

The bindInstance method can also be used to configure instances for interfaces or abstract classes.

Inject EasyDI context

In some use cases you like to have access to the EasyDI instance in one of your classes to be able to get other instances at runtime.

To achieve this use this config:

EasyDI context = new EasyDI();
context.bindProvider(EasyDI.class, ()-> context)
View on GitHub
GitHub Stars56
CategoryDevelopment
Updated24d ago
Forks9

Languages

Java

Security Score

100/100

Audited on Mar 8, 2026

No findings