Android

Dagger2 Guidelines Or Tricks For Android: You should be Following

Google+ Pinterest LinkedIn Tumblr

If you’ve managed to reach here, you probably care about performance and want to make sure you’re getting everything you need for your Android project. If that’s the case this article is for you.

This post was inspired by this video of Zac Sweers that goes through a couple of Dagger2 Tricks or you say guidelines. The Dagger2 Tricks we’re going to discuss in this article are not meant to be weird Gotchas or anything. It’s just clever ways to enable patterns in your code.

This will be a quick tutorial so don’t you dare to leave your computer for a coffee or for a Pepsi can.

Let’s get started with the first guideline.

Internal Or Private API Qualifier

Now let’s say we have this FoodModule in our Dagger graph.

@Module
abstract class FoodModule {

     @Provide 
     fun provideHotSauce() = HotSauce()

     @Provide 
     fun provideTomatoSauce() = TomatoSauce()

     @Provide
     fun provideKebab() = Kebab()

     @Provide
     fun provideBurger(tomatoSauce: TomatoSauce, hotSauce: HotSauce, kebak: Kebab) = Burger(setOf(tomatoSauce, hotSauce), kebab)  
} 

Right now anyone who wants to include this module is going to get the Sauce’s and Kebab as dependencies if they want them as well. But say I want all the Sauce’s and Kebab as a private implementation of the FoodModule and only expose Burger instance.

So, for this, we can easily use Qualifiers in Dagger to hide the dependencies. Now let’s create a new Qualifier with the name which fits best for you. I’m gonna name mine InternalApiQualifier.

@Qualifier
private annotation class InternalApiQualifier

Now in Kotlin, you can put private Qualifier in the same file as the top-level class which you using it in–In Java, you can put this in the inner class in the module. Also, you need to make the Qualifier as private.

The complete FoodModule file looks like this:

private annotation class InternalApiQualifier

@Module 
abstract class FoodModule {

     @Provide 
     @InternalApiQualifier
     fun provideHotSauce() = HotSauce()

     @Provide 
     @InternalApiQualifier
     fun provideTomatoSauce() = TomatoSauce()

     @Provide
     @InternalApiQualifier
     fun provideKebab() = Kebab()

     @Provide
     fun provideBurger(@InternalApiQualifier tomatoSauce: TomatoSauce, @InternalApiQualifier hotSauce: HotSauce, @InternalApiQualifier kebab: Kebab) = Burger(setOf(tomatoSauce, hotSauce), kebab) 
}

Now the Sauce’s and Kebab are no longer accessible outside of this FoodModule because no one outside of this class can actually even use that annotation. Pretty Cool isn’t it!

Multibinds With IntoSet Annotation

If you please look at the FoodModule again, you’ll notice that we’ve lost a bit of DI principle when providing dependencies to provideBurger method. The burger provider knows quite a bit about the type of sauces coming into it. And this is where MultiBinds will shine.

private annotation class InternalApiQualifier

@Module 
abstract class FoodModule {

     @Multibinds 
     @InternalApiQualifier
     abstract fun sauces() : Set<Sauce>  

     @Provide 
     @InternalApiQualifier
     @IntoSet  
     fun provideHotSauce() = HotSauce()

     @Provide 
     @InternalApiQualifier
     @IntoSet
     fun provideTomatoSauce() = TomatoSauce()

     @Provide
     @InternalApiQualifier
     fun provideKebab() = Kebab()

     @Provide
     fun provideBurger(@InternalApiQualifier sauces: Set<Sauce>, @InternalApiQualifier kebab: Kebab) = Burger(sauces, kebab) 
}

You see at the top we declare the Set of Sauce and annotate the sauce providers with IntoSet annotation. Now, the Dagger will gonna collect all the pieces of sauces and pass them to the burger provider. BAM!

Let’s take another example where we need to provide different interceptors when creating OkHttpClient instance.

@Module
abstact class NetworkModule {
 
     @Multibinds abstract fun interceptors() : Set<Interceptor>

     @Provide
     fun provideOkHttp(interceptors: Set<Interceptor>) = //...
}

Deferred OkHttp Initialization

A day ago Zack Sweer wrote an article on lazy initialization of OkHttpClient when working with Dagger2. You should check it out.


So, how do you like these Dagger2 guidelines? If you have any other guidelines or tricks tell them in the comments section I’d happy to put them in the list.

Thank you for being here and keep reading…

Write A Comment