Tuesday, August 20, 2019

Kotlin in Action: Chapter 10 Exercises

Chapter 10 covers annotations and reflection. To get a better grasp on this, we'll implement a very basic dependency injection framework using reflection.

Basic Dependency Injection

We'll implement a very bare bones dependency injection framework. With it you will be able to supply a class to a build method, and it will instantiate that class, as well as its dependencies.We'll limit what scenarios it will work with to simplify the problem. All classes are treated as singletons, and only a single instance of each class will be created. If a class requests a dependency that has already been instantiated, then it will be reused. We're only requiring this to work with Kotlin classes, so Java classes don't need to be considered. It'll also be assumed that the classes will have a single constructor which defines the class dependencies. We also won't handle dependencies where there could be multiple different instances of the class (so no String, Number, or other such dependencies). We also won't worry about detecting circular dependencies.

So as such, if we have classes that look like this:
class Node1
data class Node2(val node1: Node1)
data class Node3(val node1: Node1, val node2: Node2)
data class Node4(val node3: Node3)
And ran this code:
fun main() {
  val node4 = build<Node4>()
  println(node4)
}
We should get something like the following printed to the console (note that the Node1 Identifiers need to match):
Node4(node3=Node3(node1=Node1@18d87d80, node2=Node2(node1=Node1@18d87d80)))
Also note that since kotlin reflection is in a different jar, you'll need to add the following to your build.gradle file:
implementation "org.jetbrains.kotlin:kotlin-reflect:1.3.41"
As a bonus activity, after we've completed this we can modify it and add a Singleton annotation, and make it so that the class instance reference is only kept and reused if the class is annotated as Singleton, otherwise it will create a new instance each time it is needed. This will allow us to play with defining and referencing annotations.

As usual, the answers will be posted in a followup post. And here's the answers.