Independence Pattern with Dagger 2

Credit:
Miquel Beltran

For anyone who has no idea what dependence injection and Dagger 2 are. This guy is just so funny

So dependence injection is Independence Pattern and Dagger 2 help us to implement this pattern easily by getting rid of a ton of boilerplate

Instead of asking for a new instance now we ask for a provider that provides that instance

Annotation

Basic

Dagger 2 uses the following annotations:

  • @Module: define classes which provide dependencies
  • @Provides: define methods which provide dependencies
  • @Inject: request dependencies. Can be used on a constructor, a field, or a method. That mean when @Inject is added on an object also the object is not initialized anywhere but still can be used that is called as field injectionWhat happens is that dagger will search from the list of providers for the object asked by field injector and if it founds then automatically initialize thereafter
  • @Component: is an interface that will provide injected instances by using modules. Dagger will use component to generate the code that will do the dependency injection for you.

More concrete for curious guys

  • @Component.Builder: You might want to bind some instance to Component. In this case you can create an interface with @Component.Builder annotation and add whatever method we want to add to builder.
  • @Subcomponent
  • @Component(dependencies = …) see more here
  • @ContributesAndroidInjector
    class User @Inject constructor(val text = "somethingwelove"){
    }
    

So Dagger bases on annotations to make the graph and then everytime you say like
You: “I want an object A”
Dagger: “Ok, I will looking on my graph and I will see if someone offers object A”

(under the hood: Dagger find  a provider which offer object A, the provider create object A and give it to Dagger then Dagger give it to you)

Skeleton

Fist of all I’m going to make ActivityBuilder,  AppComponet,  AppModule


Then,  I create MainActivityMainActivityComponentMainActivityModule

 

Map MainActivity to ActivityBuilder (So dagger can understand MainActivity will be injected)
With@ContributesAndroidInjector, we can easily attach activities/fragments to dagger graph

@Module
abstract class ActivityBuilder {
    @ContributesAndroidInjector(modules = [(MainActivityModule::class), (RateUsDialogFragmentProvider::class), (AboutFragmentProvider::class)])
    abstract fun bindMainActivity(): MainActivity
}

Here we go. Now I call AndroidInjection.inject(this) in MainActivity and we can easily attach MainActivity to the graph then from now Dagger can provide whatever instance we want in MainActivityModule.

Remember that we call AndroidInjection.inject() every activity or fragment that we wanted to use dagger. And also, If you want to use Injection in your fragment, you should also implement HasSupportFragmentInject interface and override fragment injector in your activity. You should move these code to BaseActivity and BaseFragment then you can heritage them.

@Module
abstract class ActivityBuilder {
    @ContributesAndroidInjector(modules = [(MainActivityModule::class)])
    abstract fun bindMainActivity(): MainActivity
}

In this example we are going to have two classes:

GameData: This class provides some data required for a game session, in this case, just a string.
GameSession: This class needs the GameData, and we will inject the dependency using Dagger, rather than passing it as a parameter or creating it inside.
Without dependency injection we would have something like this: The GameData class is created inside the GameSession. Some developers will agree that this is a bad practice, for example, you want to be able to provide a different GameData for testing and you won’t be able to do that.

public class GameData {
    public final String hello = "Hello Dagger";
}
public class GameSession {
    public GameData data = new GameData();
}

Dagger will take care of injecting the new GameData() into the data variable for us, we need to tell Dagger that by using the Inject notation.

import javax.inject.Inject;

public class GameSession {
    @Inject
    public GameData data;
}

Defining dependency providers (object providers)

@Component(modules = [(AndroidInjectionModule::class), (AppModule::class), (ActivityBuilder::class)])
import dagger.Component;

@Component(modules = GameModule.class)
public interface GameComponent {
    void inject(GameSession obj);
}
import dagger.Module;
import dagger.Provides;

@Module
public class GameModule {

    @Provides
    GameData providesGameData() {
        return new GameData();
    }
}
}

 

@Provides
GameData providesGameData() {
return new GameData();
}
The GameModule has a function with the Provides annotation that tells Dagger that this function is the one that will provide the GameData.
@Component(modules = GameModule.class)
public interface GameComponent {
void inject(GameSession obj);
}
List out all of modules that we need to make components.
We also need to mark our GameModule class with the Module annotation

A nature, universe, science, music, love lover

Leave a Reply

Your email address will not be published. Required fields are marked *

Bitnami