Keeping the Daggers Sharp ⚔️

Py ⚔
Py ⚔
Oct 11, 2017 · 4 min read

Heads up, we’ve moved! If you’d like to continue keeping up with the latest technical content from Square please visit us at our new home https://developer.squareup.com/blog

Dagger 2 is a great dependency injection library, but its sharp edges can be tricky to handle. Let’s go over a few best practices that Square follows to keep mobile engineers from hurting themselves!

Favor constructor injection over field injection

  • Field injection requires the fields to be non final and non private.
  • Forgetting an @Inject on a field introduces a NullPointerException.
  • Constructor injection is better because it allows for immutable and therefore thread safe objects that don’t have a partially constructed state.
  • Kotlin eliminates the constructor injection boilerplate:
  • We still use field injection for objects constructed by the system, such as Android activities:

Singletons should be extremely rare

  • Singletons are useful when we need a centralized access to a mutable state.
  • If an object has no mutable state, it doesn’t need to be a singleton.
  • On rare occasions, we use scoping to cache instances that are expensive to create, or that are repeatedly created and thrown away.

Favor @Inject over @Provides

  • @Provides methods should not duplicate the constructor boilerplate.
  • Code is easier to understand when coupled concerns are in one place.
  • This is especially important for singletons; it’s a key implementation detail that you need to know when reading that class.

Favor static @Provides methods

  • Dagger @Provides methods can be static.
  • The generated code can directly invoke the method instead of having to create a module instance. That method call can be inlined by the compiler.
  • One static method won’t change much, but all bindings being static will result in a sizable performance increase.
  • Make your modules abstract and Dagger will fail at compile time if one of the @Provides methods isn’t static.

Favor @Binds over @Provides

  • @Binds replaces @Provides for when you’re mapping one type to another.
  • The method must be abstract. It will never be invoked; the generated code will know to directly use the implementation.

Avoid @Singleton on interface bindings

Statefulness is an implementation detail

  • Only implementations know if they need to ensure centralized access to mutable state.
  • When binding an implementation to an interface, there shouldn’t be any scoping annotation.

Enable error-prone

Several Square teams are using it to detect common Dagger mistakes, check it out.

Conclusion

These guiding principles work well for our context: small heterogeneous teams working on a large shared Android codebase. Since your context is likely different, you should apply what makes the most sense for your team.

It’s your turn! What good practices do you follow to keep your dagger code sharp?

Square Corner Blog

Buying and selling sound like simple things - and they…

Square Corner Blog

Buying and selling sound like simple things - and they should be. Somewhere along the way, they got complicated. At Square, we're working hard to make commerce easy for everyone.

Py ⚔

Written by

Py ⚔

Android baker @Square. Twitter account: @Piwai

Square Corner Blog

Buying and selling sound like simple things - and they should be. Somewhere along the way, they got complicated. At Square, we're working hard to make commerce easy for everyone.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store