Migrating from JavaX to Kodein DI
Introduction
When migrating an existing project from Java to Kotlin, chances are the project is already using a dependency injection library.
There is a big chance that this library is using javax.inject.*
annotations such as Guice or Dagger 1 & 2.
If this is the case, then migrating to Kodein should not be a hassle :)
If you are migrating a project to Kotlin & Kodein, chances are you are already sold on the benefit on using Kodein. |
Install
-
Remove the previous library dependency. Good riddance ;)
-
Replace the previous bindings with Kodein’s bindings.
-
Add the Kodein JxInject dependency (don’t forget to import the
jxInjectorModule
).
Inject
Fields & methods
If you can access a Kodein
instance, you can inject any class that uses the classic @Inject
annotation.
public class MyJavaController {
@Inject
Connection connection;
@Inject
FileSystem fs;
/* ... */
}
You can then inject existing instances of such classes by using kodein.jx
in Kotlin, or Jx.of(kodein)
in Java.
val controller = MyJavaController()
kodein.jx.inject(controller)
MyJavaController controller = new MyJavaController();
Jx.of(kodein).inject(controller);
Kodein-JxInject supports, out of the box:
-
Field injection
-
Method injection
-
javax.inject.Provider
injection
Constructors
You can create a new instance of a given class, provided that:
-
The class has only one constructor
-
Or the class have one of its constructors annotated with
@Inject
.
It is a good practice, however, to always have an @Inject
constructor, even if it is the only constructor.
public class MyJavaController {
@Inject
public MyJavaController(Connection connection, FileSystem fs) {
/* ... */
}
/* ... */
}
You can then create instances of such classes by using kodein.jx
in Kotlin, or Jx.of(kodein)
in Java.
val controller = kodein.jx.newInstance<MyJavaController>()
MyJavaController controller = Jx.of(kodein).newInstance(MyJavaController.class);
Qualifiers
JavaX dependency injection libraries use the concept of qualifier annotations while Kodein uses the very similar concept of tag.
The @Named annotation is supported out of the box and uses the string value of the annotation directly as the tag.
|
If you are using qualifiers annotations other than @Named
, you need to register "transform" functions that transform qualifier annotations into tags.
val kodein = Kodein {
import(jxInjectorModule)
/* Other bindings */
jxQualifier<MyQualifier> { MyTag(it.value) } (1)
}
<1>: Transforms a MyQualifier
qualifier annotation into a MyTag
Kodein tag.
Use Kodein’s Kotlin API
Don’t forget that kodein-jxinject
should only be used in or on Java code!
If you are transforming Java code into Kotlin, than take the time to migrate the injection code to Kodein’s native api.
Simply: Replace all @Inject
annotated fields with their kodein.instance()
counterparts.