Skip to content

Latest commit

 

History

History
41 lines (29 loc) · 2.32 KB

dependency-injection.md

File metadata and controls

41 lines (29 loc) · 2.32 KB

Overview

At its core, dependency injection is just the principle of "tell, don't ask" put into practice; for instance, if a class needs to use the MediaWikiApi, it should be handed an instance of the class rather than reaching out to get it. This has the effect of decoupling code, making it easier to test and reuse.

Dependency Injection in the Commons app

We use Dagger 2 as our dependency injection engine. Dagger is a fully static, compile-time dependency injection framework for both Java and Android. Dagger aims to address many of the development and performance issues that have plagued reflection-based solutions that came before it, but it does come at something of a cost in complexity.

For more information about Dagger, take a look at the Dagger user guide.

Dagger configuration in the Commons app

The top level CommonsApplicationComponent pulls together configuration for injection across the app. The most important files to understand

  • if you need to add a new Activity, look at ActivityBuilderModule and copy how injection is configured. The BaseActivity class will take care of the rest.
  • if you are adding a new Fragment, look at FragmentBuilderModule
  • if you are adding a new ContentProvider, look at ContentProviderBuilderModule
  • if you are adding a new Service, look at ServiceBuilderModule
  • other dependencies are configured in CommonsApplicationModule

"Provider" methods

Dagger will resolve the method arguments on provider methods in a module (or the constructor arguments when annotated with @Inject) and build the objects accordingly - either by calling another provider method or by looking for a constructor on a class that has the @Inject annotation. Dagger takes care of managing singletons, just annotate with the @Singleton annotation. For instance,

@Provides
@Singleton
public SessionManager providesSessionManager(MediaWikiApi mediaWikiApi) {
    return new SessionManager(application, mediaWikiApi);
}

If your code injects an interface (in this case, MediaWikiApi) then Dagger needs to know which concrete class to use. This comes by way of a provider method:

@Provides
@Singleton
public MediaWikiApi provideMediaWikiApi() {
    return new ApacheHttpClientMediaWikiApi(BuildConfig.WIKIMEDIA_API_HOST);
}