I'm building an app with some features: a ContentProvider a SyncAdapter, a Job service and related persistence logic. On top on these there are the Activities with the UI. I'm trying to put all said features in a separate library module, because in theory their logic is stand-alone and would be reusable by any application.
Now comes Dagger2. The first node (main Component) of my library's dependency graph does need to provide Context, and this Context has to be injected from the Application, because the library scope has the same lifecycle of the application. To be self contained, obviously, my library should not directly use my Application class.
These are the possibilities I thought of:
What is the correct way to do this?
Dagger constructs instances of your application classes and satisfies their dependencies. It uses the javax. inject. Inject annotation to identify which constructors and fields it is interested in. Use @Inject to annotate the constructor that Dagger should use to create instances of a class.
Dagger automatically generates code that mimics the code you would otherwise have hand-written. Because the code is generated at compile time, it's traceable and more performant than other reflection-based solutions such as Guice. Note: Use Hilt for dependency injection on Android.
Dagger is a fully static, compile-time dependency injection framework for Java, Kotlin, and Android. It is an adaptation of an earlier version created by Square and now maintained by Google.
Dagger 2 is a compile-time android dependency injection framework that uses Java Specification Request 330 and Annotations. Some of the basic annotations that are used in dagger 2 are: @Module This annotation is used over the class which is used to construct objects and provide the dependencies.
Dagger 2 for Android comes to the rescue. It provides the concept of AndroidInjector
, which is a Component
that can be used to inject an instance in a static way, without having to know the dependency provider. Moreover, using the Dagger-
prefixed classes provided out of the box, the injected dependencies look like coming from nowhere. Awesome.
All you have to do is declare in the library a top-level Module
which is installed in the Application Component
. This Module
will provide all the dependencies and the SubComponent
s needed by the library, which will automatically inherit the @AppContext Context
that you seeded in the dependency graph, ready to be injected anywhere in you library, as well as every dependency you provide through the main Application Component
.
Here's a short example (written in Kotlin):
@Component(modules = [
AndroidSupportInjectionModule::class,
AppModule::class,
LibraryModule::class //plug-in the library to the dependency graph
])
@Singleton
interface AppComponent : AndroidInjector<App> {
@Component.Builder
abstract class Builder : AndroidInjector.Builder<App>() {
@BindsInstance
abstract fun appContext(@AppContext context: Context)
override fun seedInstance(instance: App) {
appContext(instance)
}
}
}
Edit: extended examples
An example of the Application subclass:
// DaggerApplication provides out-of-the-box support to all the AndroidInjectors.
// See the class' code to understand the magic.
public class App extends DaggerApplication {
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
// We only provide its own Injector, the Application Injector,
// that is the previous AppComponent
return DaggerAppComponent.builder().create(this);
}
And in your Android library:
@Module
public abstract class LibraryModule {
@ContributesAndroidInjector
public abstract LibraryActivity contributeLibraryActivityInjector();
}
public class LibraryActivity extends DaggerAppCompatActivity {
@Inject
@AppContext
Context appContext;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceSate);
// here you automagically have your injected application context!
ExternalSingleton.getInstance(appContext)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With