One fact: it is more performant to make the all provider methods inside Modules static.
But for Modules that have bootstrap dependencies, this is impossible. Let’s take ActivityModule as example.
@Module class ActivityModule(private val activity: AppCompatActivity) { @Provides fun activity(): AppCompatActivity = activity @Provides fun layoutInflater(activity: AppCompatActivity): LayoutInflater = LayoutInflater.from(activity) @Provides fun fragmentManager(activity: AppCompatActivity) = activity.supportFragmentManager @Provides @ActivityScope fun screensNavigator(activity: AppCompatActivity) = ScreensNavigator(activity) } We can easily make fun layoutInflater(), fragmentManager() and screensNavigator static methods.
Components can have multiple Modules. So if you have huge Modules that provide tons of services, it is good to split it up.
Let’s create a UseCaseModule to hanle all the UseCases.
@Module class UseCasesModule { @Provides fun fetchQuestionsUseCase(stackOverflowApi: StackoverflowApi) = FetchQuestionsUseCase(stackOverflowApi) @Provides fun fetchQuestionDetailsUseCase(stackOverflowApi: StackoverflowApi) = FetchQuestionDetailsUseCase(stackOverflowApi) } Some dagger conventions:
Components can use more than 1 module. Modules of the same Component share the same object-graph. Dagger automatically instantiate modules with no argument constructor.
In previous post, we introduced the component dependencies. But there is one interesting subtlety: If Component B depends on Component A, B has access to all A’s exposed objects. Note that there is a difference between what a component exposes and what it provides.
Let’s look at PresentationComponent and ActivityComponent.
@PresentationScope @Component(dependencies = [ActivityComponent::class], modules = [PresentationModule::class]) interface PresentationComponent { fun inject(fragment: QuestionsListFragment) fun inject(questionDetailsActivity: QuestionDetailsActivity) } Here in PresentationComponent, even though it provides all the objects that QuestionsListFragment and QuestionDetailsActivity need, it exposes nothing.
Let’s look at the PresentationComponent more closely.
One strange thing is that PresentationModule has ActivityComponent as its dependency, and it @Provide all the objects provided by ActivityComponent already.
This is rather ugly, can we do something about it?
The answer is Component Dependencies.
The idea is that we can make PresentationComponent depends on ActivityComponent. That way, PresentationComponent automatically gets access to all the objects exposed by ActivityComponent.
After this change, it looks like this:
In previous post, we replaced our Pure Dependency Injection with Dagger2. But, the conversion is without too much thoughts.
One improvement we can do is to follow Dagger’s convention of using Component as Injector.
We can make the following mental models:
Dagger’s @Module is for creating objects. Dagger’s @Component is for injecting objects into application classes.