Android: Dagger 2 — Part 2

Mohd Irfan
3 min readApr 26, 2020

Part 1 Url

https://medium.com/@mohdirfanali/android-dagger-2-part-1-90c6431a3957

Components and subcomponents are also called graphs because they are attached to your application or feature’s lifecycle. You should instantiate graphs one time inside that lifecycle to avoid redundant objects. Responsibility of providing dependencies to requested classes falls onto graphs.

In the first part, we explored dagger annotations and how to pass dependencies into required classes, such as passing LocalDataSource as dependency inside UserRepository class.

In the first part, we also focused on providing dependencies to those classes which are being instantiated manually. But what about such classes whom android system instantiates such as Activity, Fragments, Broadcast Receiver, Services and so on.

Dagger can instantiate classes developed by developers, but it can’t create Activity or Fragment objects. For activities- initialisation code needs to go inside onCreate() method and for fragments- it needs to go inside onAttach().

That means we can’t use @Inject annotation on these class constructors.

To provide dependency for such classes use field Injection instead.

One of the considerations with Dagger is that injected fields cannot be private. They need to have at least package-private visibility like in the above activity.

But as we discussed in part 1, To satisfy target class dependency Dagger searches for that dependency inside the component(Graphs). In the above code, we are telling dagger to provide UserRepositry to FieldInjectionActivity but we also need to declare FieldInjectionActivity inside a component so that dagger knows from which module it should provide UserRepositry to FiledInjectionActivity.

In other words “you need to tell Dagger about an object (FieldInjectionActivity in this case) that requires a dependency to be injected”

This inject function tells dagger that FieldInjectionActivity wants to access graphs and request injection. Dagger needs to satisfy all dependency FieldInjectionActivity requires.

Now to inject an object in FieldInjectionActivity you would use this app component and call the inject method on it.

See onCreate() method in above code. Notice we are calling inject method on DaggerAppComponent before super call. It is just to avoid issues with fragment restoration. During the restore phase in super.onCreate(), an activity attaches fragments that might want to access activity bindings.

In fragments, injection can be done before or after calling super.onAttach()

Now just to recap,

  1. By using @Inject on userRepository field we are informing dagger that this activity is Requesting dependency to be injected.
  2. We are declaring inject(activity: FieldInjectActivity) in AppComponent so dagger can satisfy injectionRequest.
  3. Rest is just performing required tasks on a dependency object.

The recommended method to add types or dependency is using @Inject annotations on constructors but sometimes it is not possible, in such scenarios either use Field injection or Modules depending on your requirements.

Now you know everything there is to know about Dagger, how it works, and how to use it.

Implement it is as per your requirements. One practice there is to divide your graphs as follows

  1. Application Graph
  2. Authentication Graph
  3. Main Graph.

Application Graph : To satisfy dependencies which need to be instantiated one time in the whole application lifecycle. Such as retrofit, Room Database etc.

Authentication Graph : Almost every application has an authentication module in it. Create this graph for satisfying this module file dependency.

Main Graph : Satisfy the rest of the app dependencies from this graph, though it can further be divided as per module basis.

--

--