Introducing fb-android-dagger - a helper lib for using dagger with Android

A while back, Square released a new dependency injection framework called dagger, emphasizing simplicity and performance (via compile-time code generation rather than runtime reflection). Dagger actually has no Android dependencies and thus can be used in other contexts, but it has gained traction among Android developers. As I started working with it, it quickly became clear that it would be handy to have a set of reusable base classes that integrate dagger with the standard Android components like Application, Service, BroadcastReceiver, Activity, and Fragment. And so, fb-android-dagger was born. I open sourced it about a year ago, and a few people seem to be using it, so it's probably (past) time I introduced it.

Creating object graphs

I'll skip over the dagger basics, as they're explained well on Square's dagger page, but I'll note that a useful implementation pattern that quickly emerged is to have a component base class do the ObjectGraph initialization and injection of "this" in its first lifecycle method (e.g. Activity.onCreate()). To initialize the graph, that code needs the set of applicable dagger modules, so the base class defines a getModules() method which it expects subclasses to override by supplying the modules they want to contribute to the graph.

Here's a typical subclass implementation of getModules():


public class MyActivity extends InjectingActivity {

// ...

    @Override protected List<Object> getModules() {
        List<Object>
        modules = super.getModules();
        modules.add(new MyModule());
        return modules; 
    } 
} 

s you can see, the idea is for the module list to be built cooperatively via the getModule() overrides in the chain of classes deriving from the injecting base class. Each class' getModules() method first gets its superclass' module list, add its own modules to the list and returns the combined list.

fb-android dagger's set of component base classes each implement this mechanism, in a lifecycle method appropriate to the component:

  • InjectingApplication (onCreate)
  • InjectingBroadcastReceiver (onReceive)
  • InjectingService (onCreate)
  • InjectingActivity (onCreate)
  • InjectingFragmentActivity (onCreate)
  • InjectingPreferenceActivity (onCreate)
  • InjectingFragment (onAttach)
  • InjectingListFragment (onAttach)
  • InjectingDialogFragment (onAttach)

In addition, the graphs that fb-android-dagger creates are scoped to their associated components, so the graph created by MyActivityOne is distinct from the graph created for MyActivityTwo. However, it does reuse and extend graphs created by other components, working "outward" from the Application graph:

  • an Application-scope graph is created by InjectingApplication
  • InjectingBroadcastReceiver creates a BroadcastReceiver-scoped graph that extends the Application-scope graph.
  • InjectingServiceReciever creates a Service-scoped graph that extends the Application-scoped graph
  • InjectingActivity, InjectingFragmentActivity, and InjectingPreferenceActivity create Activity-scoped graphs that extend the Application-scoped graph.
  • InjectingFragment, InjectingDialogFragment, and InjectingListFragment create Fragment-scoped graphs that extend their associated Activity's graph.

Helper modules

fb-android-dagger also provides a set of dagger modules and qualifier annotations to facilitate injection of objects relevant to their component type.

For example, a class injected by an Activity-scope graph could get the Activity's context and the Application context injected like so:


class Foo1 { 
    @Inject @Application Context appContext;
    @Inject @Activity Context activityContext; // ... 
}

A class can also access relevant components themselves, directly:


class Bar { 
    @Inject Application theApp;
    @Inject Activity myActivity; 
    @Inject Fragment myFragment; // ... 
}

Feel free to give a try!

Source is on Github

Maven users can download from Maven Central:


<dependency> 
	<groupId>com.fizz-buzz</groupId>
    <artifactId>fb-android-dagger</artifactId>
    <version>1.0.3</version> 
</dependency>