Dagger 2

Jintin
AndroidPub
Published in
3 min readNov 19, 2017
Photo by Thanh Tran on Unsplash

Dagger is a Dependency Injection framework written in Java. Though there’s lots of discussion around Android development, it’s pure Java. You can use it directly without Android.

Inversion of Control

Let’s start from why we need Dependency Injection. Let see what problem with this example?

public class A {
public void doSomething() {
B b = new B();
b.doSomething();
}
}

Class A is highly coupled with Class B since it rely on the real instance, b. We can hardly replace it without touch the A class. We have two options to solve it:

  1. Inject B in Constructor parameter.
  2. Inject B as Method parameter.
// 1. Inject in Constructor Parameter
public class A {
B b;
public A(B b) {
this.b = b;
}
public void doSomething() {
b.doSomething();
}
}
// 2. Inject in Method Parameter
public class A {
public void doSomething(B b) {
b.doSomething();
}
}

This way we can avoid new an object inside A. What is the benefit for us? We can swap the b instance into another b’ or c at anytime we want. For unit-test perspective, it’s also easy to mock since we can fake the object outside of the A Class.

It’s a beautiful world with all these two inject patterns, but let's replace A Class with any Activity in your mind. Have you ever write any Constructor or Method call by upper Class for Activity? The answer is NO, Android framework will handle all the initialization thing for us. All the instantiate is behind the scenes and we don’t manipulate the Activity instance directly. Which is good and bad, and that is where Dagger take place to help us reduce the coupling by different inject method.

Dagger Injection

Dagger 2 use several annotations to distinct different roles in injection and generate helper Class satisfy our need.

  1. @Provide : Method annotation indicate it can provide object for injection.
  2. @Module : Class annotation where a set of @Provide method place.
  3. @Inject : object which wait for inject.
  4. @Component : inject helper Class which bind @Module.

It’s too complicate to describe. Let’s see some sample code first.

@Module
public class BModule {
@Provides
B provideB
() {
return new B();
}
}
@Component(modules = BModule.class)
public interface BComponent {
void inject(A a);
}
public class A {
@Inject
B b;

public A() {
init();
}

public void init() {
BComponent component = DaggerBComponent
.builder()
.bModule(new BModule())
.build();

component.inject(this);
}

public void doSomething() {
b.doSomething();
}
}

We only need indicate which object we want to inject with @Inject annotation. @Provide indicate provideB can help instatiateB for us. @Module is all @Provide functions place. And @Component describe BComponenet is the coordinator help BModule which contains B inject into A. BTW, you can wrap the component initialization into another place if you like.

Conclusion

It’s just a simple tutorial describe each component in Dagger. There are more complex scenario in our real life. But now we know by leverage Dagger we get the ability to get rid of the high coupling between B and A. You can start to think about how to separate each dependency by injection like the “Dagger” literally do. Wish you a clean code.

Reference

--

--

Jintin
AndroidPub

Android/iOS developer, husband and dad. Love to build interesting things to make life easier.