Skip to content

Injecting Dependencies

Injector Context

Every project should have at least one Injector Context instantiated. It is responsible for holding objects references so you can ask for them anytime later.

val injector = Injector.creator()
Injector injector = Injector.creator();

Constructor Injection

In order to keep dependency injection experience as close as possible to vanilla java, Injector opted for constructor injection as its main (and only) injection mechanism. That's a good strategy towards immutability and other clean-code good practices.

Making classes injectable

Injector will allow developers to expose objects in two ways:

  • Singleton - classes exposed like this will have only one instance of its type registered in the Injection Context. To expose singleton classes you should annotated them with the injector.Singleton annotation.
  • Regular classes - as the name states this isn't a special type but a class in which a new instance will be created every time it should be injected. To expose normal classes you should annotated them with the injector.New annotation.
@Singleton class SingletonServiceA
@New class RegularServiceB

@Singleton class SingletonServiceB(
    val serviceA: SingletonServiceA,
    val serviceB: RegularServiceB
)

@Singleton class SingletonServiceC(
    val serviceA: SingletonServiceA,
    val serviceB: RegularServiceB
)
@Singleton class SingletonServiceA {}
@New class RegularServiceB {}

@Singleton class SingletonServiceB {

    final SingletonServiceA serviceA;
    final RegularServiceB serviceB;

    SingletonServiceB( SingletonServiceA serviceA, RegularServiceB serviceB ) {
        this.serviceA = serviceA;
        this.serviceB = serviceB;
    }
}

@Singleton class SingletonServiceC {

    final SingletonServiceA serviceA;
    final RegularServiceB serviceB;

    SingletonServiceC( SingletonServiceA serviceA, RegularServiceB serviceB ) {
        this.serviceA = serviceA;
        this.serviceB = serviceB;
    }
}

If we instantiate an Injector Context, we're going to have one instance of SingletonServiceA, SingletonServiceB and SingletonServiceC - as they are singletons - and two instances of RegularServiceB - as it is a regular class.

Retrieving your injectable service

Once you expose your services you'll be able to ask the Injector Context for instances and it will take care of instantiate them and return the instance as you need.

val injector = Injector.creator()
val serviceC = injector.instanceOf( SingletonServiceC.class )
Injector injector = Injector.creator();
SingletonServiceC serviceC = injector.instanceOf( SingletonServiceC.class );

Injector will respect the aforementioned rules regarding singletons, thus anytime you ask for an instance of SingletonServiceC you're going to receive the same instance. Note though that you're going to receive different instances if you ask for an instance of RegularServiceB.