Skip to main content

Dagger: A Dependency Injection Framework for Android and Java

Dagger is a new dependency injection framework for Android and Java. I went to a meetup yesterday to learn more about it. These are my notes:

The talk was by Jake Wharton who works at Square.

Every single app has some form of DI. You can do DI even if you're not using a library for doing it. The goal of DI is to separate the behavior of something from its required classes. If you've ever used a constructor to receive stuff, you've done a simple version of DI.

Square used Guice heavily.

Problems with Guice:
Config problems fail at runtime. 
Slow initialization, slow injection, and memory problems.

These are worse on Android. It causes the OS to load all the code for your app at once. This caused their app to take 2 seconds to start.

They called Dagger "Object Graph" initially.

Goals of Dagger:

Static analysis of all dependencies and injections. 
Fail as early as possible--compile time, not runtime.
Eliminate the need to do reflection of methods and annotations at runtime. Reflection in Dalvik is really slow.
Have negligible memory impact.

Jesse Wilson wrote it over the course of 5 weeks. He previously worked on Guice and Dalvik.

Square switched from Guice to Dagger in a fairly short period of time.

The name Dagger refers to "directed acyclic graph".

An ObjectGraph is the central dependency manager and injector.

@Module + @Provides

@Inject

@Singleton

Modules are meant to be composed together.

@Inject is required.

Field injection or constructor injection.

Dependencies can be stored in private final fields.

If you have @Inject, you don't have to say @Provides.

Injected fields cannot be private or final. They can be package protected.

Object graphs can be scoped. One object graph is a superset of another. For instance, you might create a new object graph once the user logs in that contains all of the objects that are require a user object.

Android

The Android platform makes it really hard to test your apps. He showed how they deal with it.

The ObjectGraph is just another object. Hence, you can pass it around like a normal object.

There's one pain point in Dagger. All injection points must be listed on a module. This is used for aggressive static analysis.

Use overrides to facilitate testing.

He showed how to integrate with Gradle.

They have a "Debug Drawer" in their apps. It is hidden in the UI, but lets you configure all sorts of debug settings.

U+2020 is a sample app to show how to do all of this.

Using DI Incorrectly

Do NOT ignore the pattern.

Do NOT make every class use the pattern. Use it for the big things, such as the things that talk to a remote API.

Do NOT store dependencies as static fields.

Other Stuff

The Android docs say not to use DI. That advice is stale. Those complaints don't apply to Dagger.

Dagger is developer and debugger friendly.

The Future

Dagger has been out for 18 months.

They're working on the next major version, version 2.0.

Google is leading the development of the next version.

It won't use any reflection.

Dagger is not Android specific.

They're getting rid of injects lists.

Components encapsulate dependencies.

There will be dedicated annotations to denote scopes.

See squ.re/dagger2.

Questions

They use protocol buffers for their APIs. They use a schema for their APIs.

They have code that can generate a GraphViz file that shows you your dependency graph.

In their apps, they have a network module, an Android module, an app module, etc.

There's an IntelliJ plugin that lets you jump between @Inject and @Provides.

Comments

Popular posts from this blog

Ubuntu 20.04 on a 2015 15" MacBook Pro

I decided to give Ubuntu 20.04 a try on my 2015 15" MacBook Pro. I didn't actually install it; I just live booted from a USB thumb drive which was enough to try out everything I wanted. In summary, it's not perfect, and issues with my camera would prevent me from switching, but given the right hardware, I think it's a really viable option. The first thing I wanted to try was what would happen if I plugged in a non-HiDPI screen given that my laptop has a HiDPI screen. Without sub-pixel scaling, whatever scale rate I picked for one screen would apply to the other. However, once I turned on sub-pixel scaling, I was able to pick different scale rates for the internal and external displays. That looked ok. I tried plugging in and unplugging multiple times, and it didn't crash. I doubt it'd work with my Thunderbolt display at work, but it worked fine for my HDMI displays at home. I even plugged it into my TV, and it stuck to the 100% scaling I picked for the othe

Drawing Sierpinski's Triangle in Minecraft Using Python

In his keynote at PyCon, Eben Upton, the Executive Director of the Rasberry Pi Foundation, mentioned that not only has Minecraft been ported to the Rasberry Pi, but you can even control it with Python . Since four of my kids are avid Minecraft fans, I figured this might be a good time to teach them to program using Python. So I started yesterday with the goal of programming something cool for Minecraft and then showing it off at the San Francisco Python Meetup in the evening. The first problem that I faced was that I didn't have a Rasberry Pi. You can't hack Minecraft by just installing the Minecraft client. Speaking of which, I didn't have the Minecraft client installed either ;) My kids always play it on their Nexus 7s. I found an open source Minecraft server called Bukkit that "provides the means to extend the popular Minecraft multiplayer server." Then I found a plugin called RaspberryJuice that implements a subset of the Minecraft Pi modding API for B

Creating Windows 10 Boot Media for a Lenovo Thinkpad T410 Using Only a Mac and a Linux Machine

TL;DR: Giovanni and I struggled trying to get Windows 10 installed on the Lenovo Thinkpad T410. We struggled a lot trying to create the installation media because we only had a Mac and a Linux machine to work with. Everytime we tried to boot the USB thumb drive, it just showed us a blinking cursor. At the end, we finally realized that Windows 10 wasn't supported on this laptop :-/ I've heard that it took Thomas Edison 100 tries to figure out the right material to use as a lightbulb filament. Well, I'm no Thomas Edison, but I thought it might be noteworthy to document our attempts at getting it to boot off a USB thumb drive: Download the ISO. Attempt 1: Use Etcher. Etcher says it doesn't work for Windows. Attempt 2: Use Boot Camp Assistant. It doesn't have that feature anymore. Attempt 3: Use Disk Utility on a Mac. Erase a USB thumb drive: Format: ExFAT Scheme: GUID Partition Map Mount the ISO. Copy everything from