Android Dagger2 Inject via Fields (for non-Activity/Fragment class)

December 28, 2018

For normal classes, you should use inject via contructor.

Refer to Activity and Fragment injection as well.

Unless you cannot instantiate the class yourself (e.g. Worker for WorkManager), then you need injection via fields.

class ProcessImageWorker constructor(context : Context, params : WorkerParameters)
    : Worker(context, params) {

    @Inject
    lateinit var pinDao: PinDao

    override fun doWork(): Result {
        App.daggerAppComponent.inject(this)
    }
}

Edit your AppComponent class (refer to Dagger 2 tutorial).

@Singleton
@Component(modules = [(AndroidInjectionModule::class), (AppModule::class), (ActivityModule::class), (FragmentModule::class)])
interface AppComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: Application): Builder

        fun build(): AppComponent
    }

    fun inject(luaApp: LuaApp)

    fun inject(worker: ProcessImageWorker)
}

Edit Application class to save the DaggerAppComponent.

class LuaApp : Application(), HasActivityInjector {
    @Inject
    lateinit var activityInjector: DispatchingAndroidInjector<Activity>

    @Inject
    lateinit var fragmentInjector: DispatchingAndroidInjector<Fragmen

    override fun onCreate() {
        super.onCreate()

        // initialize Dagger
        val component = DaggerAppComponent.builder().application(this).build()
        component.inject(this)
        App.daggerAppComponent = component
    }

    override fun activityInjector(): AndroidInjector<Activity> = activityInjector

    override fun supportFragmentInjector(): AndroidInjector<Fragment> = fragmentInjector
}

App singleton class.

object App {
    lateinit var daggerAppComponent: AppComponent
}
This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.