question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to provide the Application / Application Context to Singleton dependencies in Dagger 2.11?

See original GitHub issue

This is a question I have in my project: https://github.com/vestrel00/android-dagger-butterknife-mvp/issues/42. I currently have a working solution: https://github.com/vestrel00/android-dagger-butterknife-mvp/pull/43. However, I’m hoping that future versions of Dagger may make it simpler (not that it isn’t simple already).

Currently, Dagger 2.11 does not allow the Application instance to be implicitly provided using the same method used to provide Activity and Fragment instances;

abstract class AppModule {
    @Binds
    @Singleton
    abstract Application application(App app);
}

The above gives the following compile-time error:

error: [dagger.android.AndroidInjector.inject(T)] com.vestrel00.daggerbutterknifemvp.App cannot be provided without an @Inject constructor or from an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.

The current solution (and what I consider a workaround) is to store the Application instance in a module so that it may be provided;

@Module
class ApplicationProviderModule {

    private final Application application;

    ApplicationProviderModule(Application application) {
        this.application = application;
    }

    @Provides
    @Singleton
    Application application() {
        return application;
    }
}


@Module(includes = {
        AndroidInjectionModule.class,
        ApplicationProviderModule.class
})
abstract class AppModule {
    ...
}

public class App extends Application implements HasActivityInjector {
    ...
    @Override
    public void onCreate() {
        super.onCreate();
        DaggerAppComponent.builder()
                .applicationProviderModule(new ApplicationProviderModule(this))
                .build()
                .inject(this);
    }
    ...
}

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:20

github_iconTop GitHub Comments

17reactions
vestrel00commented, Aug 6, 2017

Thanks for that info! I sometimes choose readability over performance (of auto-generated code) given its pros and cons. I’ll play the devils advocate here and just update the comment to:

    @Binds
    @Singleton
    /*
     * Singleton annotation isn't necessary since Application instance is unique but is here for
     * convention. In general, providing Activity, Fragment, BroadcastReceiver, etc does not require
     * them to be scoped since they are the components being injected and their instance is unique.
     *
     * However, having a scope annotation makes the module easier to read. We wouldn't have to look
     * at what is being provided in order to see understand scope.
     */
    abstract Application application(App app);

Just my preference. Other people could totally disagree =)

10reactions
LeoDroidCodercommented, Jul 24, 2018

For me, this representation looks better:

App : DaggerApplication() {

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.builder()
            .create(this)
    }
}
@Singleton
@Component(
    modules = arrayOf(
        AppModule::class,
        //...
    )
)

interface AppComponent : AndroidInjector<App> {

    @Component.Builder
    abstract class Builder : AndroidInjector.Builder<App>() {
    }
}
@Module(includes = arrayOf(AndroidSupportInjectionModule::class, ...))
abstract class AppModule {

    @Singleton
    @Binds
    @AppContext
    abstract fun provideContext(app: App): Context
}
@Qualifier
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
annotation class AppContext

and finally you can use it in a way: @AppContext context : Context

Read more comments on GitHub >

github_iconTop Results From Across the Web

Inject dependencies into Singleton Dagger 2.11 - Stack Overflow
Inject dependencies into Singleton Dagger 2.11 ... I have application-level scoped Singleton classes TaskRepository and AppConfig, which have ...
Read more >
Dependency Injection with Dagger - josdem
Dagger is a dependency injection framework for both Java and Android. This time I will show you how to create a basic project...
Read more >
[HOW-TO] Android Dagger (2.11–2.17) Butterknife (8.7-8.8 ...
This is used to annotate dependencies that behave like a singleton within the lifespan of an Activity, Fragment, and child Fragments instead of ......
Read more >
Using Dagger 2 for dependency injection in Android - Tutorial
Dagger 2 is dependency injection framework. It is based on the Java Specification Request (JSR) 330. It uses code generation and is based...
Read more >
Dependency Injection with Dagger 2 - CodePath Cliffnotes
Android Studio by default will not allow you to navigate to generated Dagger 2 code as legitimate classes because they are not normally...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found