Dagger 2 @Binds vs @Provides

Elye
Nov 14, 2018 · 4 min read

Beginning Dagger 2.12 (sorry, I know its quite some time back.. but still worth understanding it), there’s this new feature called @Binds added to Daggers. There are already some blogs about it. However reading them still makes me wonder what advantage it has to the old faithful @Provides that we have in our modules.

As my goal is to make things as clear as possible, so I’m writing this after making my own investigation on it, in a way that clears my questions.

What’s the different in term of coding

@Provides

@Module
class MyModule {
@Provides
fun getInjectClass(injectObject: InjectClass): InjectInterface {
return injectObject
}

}
class InjectClass @Inject constructor(): InjectInterface
interface InjectInterface

@Binds

@Module
abstract class MyModule {
@Binds
abstract fun getInjectClass(injectObject: InjectClass):
InjectInterface
}
class InjectClass @Inject constructor(): InjectInterface
interface InjectInterface

From the above, there’s no obvious clear advantage of @Binds over @Provides. One got turn into an abstract class and function, while the other is a concrete one. It doesn’t reduce any verbosity (or boilerplate).

So what’s the advantage of @Binds?

To know that, let’s look at some history

Historically…

In the very-very-very early stage of Dagger, there’s no such thing such as @Module. @Module are in fact not needed for having Dagger 2 to work (check out world’s shortest dagger 2 code).

However people complaints and wanted to group related dependents together. So the Dagger 2 developer gave in and create this famously known feature call @Module which has it’s benefits as wanted by many.

Nonetheless, the existence of @Module with @Provides does introduce some overhead in the generated code. So @Binds was introduced to help that.

Prove it to me…

Using the above code, (together with the @Component which is not shown in the code snippet above)… let’s check out the different

Extra module factory classes

The below are the classes generated.

Note that @Provides generates the MyModule_GetInjectClassFactory class, which doesn’t exist in @Binds

What does the class looks like? Wow, quite a bit of codes..

Besides, this is only for one InjectClass. But if we have more than 1 of them in our module, each of them will generate a factory class itself

@Provides
fun getInjectClass(injectObject: InjectClass): InjectInterface {
return injectObject
}

@Provides
fun getInjectClass2(injectObject2: InjectClass2): InjectInterface2 {
return injectObject2
}
@Provides

fun getInjectClass3(injectObject3: InjectClass3): InjectInterface3 {
return injectObject3
}

Imagine how that will adds to our DexCount and Size of the App!! 😱

Extra layer of module wrapper

Other than the extra Module Factor class, if we’re to examine our DaggerMyComponent class created, we would see the code size different.

Pink is those in @Provides only while green is those in @Binds only

The @Provides generates 52 lines of codes, and the @Binds only generate 29 lines of codes (~40% reduction!!).

If you trace the code you’ll see the flow as below.

Look at how much concise @Binds is in creating the InjectObject?

In short, not only @Binds reduce the number of lines, it also reduce the object creation as well as operation flow.

So let’s change everything to @Binds?

Unfortunately, @Binds only works based on the rules below

@Binds methods must have only one parameter whose type is assignable to the return type

So only a single parameter, and the type return is typically the interface of the given parameter object.

Having said that, the other tips is consider using static function for @Provides which would help also reduce some generated codes.

Check out the part 1 section of the below blog to get more insight (after reading the above, you might get a clearer understanding of the blog below)


I hope this post is helpful to you. You could check out my other interesting topics here.

Follow me on medium, Twitter or Facebook for little tips and learning on Android, Kotlin etc related topics. ~Elye~

Elye

Written by

Elye

Learning and Sharing Android and iOS Development

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade