MeLine MeLine - 3 years ago 214
Android Question

Dagger can not provide injection with Kotlin

I have this issue when I try to use Kotlin and Dagger 2 .

"interface cannot be provided without an @Provides- or @Produces-annotated method.”

This is my Module class:

@Module
class MenuActivityModule(@NonNull private val menuActivity: MenuActivity) {

@Provides
@MenuActivityScope
fun provideGameScreenDimensions(application: Application) =
GameScreenDimension(application.resources)

@Provides
@MenuActivityScope
fun provideAudio() =
AndroidAudio(menuActivity)

@Provides
@MenuActivityScope
fun providePowerManager() =
menuActivity.getSystemService(Context.POWER_SERVICE) as PowerManager

@Provides
@MenuActivityScope
fun provideWakeLock(@NonNull powerManager: PowerManager) =
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Preferences.APPLICATION_TAG)
}

This is a part of my Activity class, where I inject some variables with Dagger:

class MenuActivity : BaseActivity {

@Inject
lateinit var myAudio: Audio
@Inject
lateinit var wakeLock: PowerManager.WakeLock
@Inject
lateinit var apiService : ApiService
@Inject
lateinit var sharedPref : SharedPreferences
@Inject
lateinit var gameDimension : GameScreenDimension

init {
DaggerMenuActivityComponent.builder()
.menuActivityModule(MenuActivityModule(this))
.build()
.inject(this)
}
//more code
}


Audio.kt is interface and Dagger has problem to inject it. Inside the activity module I am returning AndroidAudio
instance, which implements Audio interface. I am not sure what is the problem here. In Java I have had many times injection of interfaces and I never had this issue before.
If somebody can help me I will be so happy.
Thanks!

Answer Source

I think the solution for your problem is very simple and also not so obvious unfortunately.

Because Kotlin does not require type to be specified on methods return, you can easily write something like this:

@Provides
@MenuActivityScope
fun provideAudio() =
        AndroidAudio(menuActivity)

And the compiler will not complain about that, but in this case Dagger will provide AndroidAudio object for injection. In you Activity you are looking for Audio object for injection. So if you change this code to be:

@Provides
@MenuActivityScope
fun provideAudio(): Audio =
        AndroidAudio(menuActivity)

Everything should be ОК. Give a try and tell me if something does not work. Thanks.

BTW : When I use Dagger with Kotlin I aways specify the type of returned value, because usually that is gonna be the type of the injected variables or the type of the variable which you are going to use in your dagger module.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download