Reputation: 1806
So, I have this issue which I think I understand what's happening but I don't know a way out. Note: I'm pretty new to Dagger 2 ...I'm coming from SpringBoot and it pretty lazy out there, so take it easy on me.
I have a module that provides three methods, the last method depends on the first two methods like below:
@Module
class CoreModule {
@Provides
@Named("appName")
fun appName() : String{
return "Uburu Store"
}
@Provides
@Named("appVersion")
fun appVersion() : String {
return "0.0.1"
}
@Provides
@Named("appInfo")
fun appInfo(appName: String, appVersion: String) : String {
return "$appName Version:: $appVersion"
}
}
I'm getting an error that:
[Dagger/MissingBinding] java.lang.String cannot be provided without an @Inject constructor or an @Provides-annotated method.
My ApplicationComponent class:
@Component(modules = [(CoreModule::class), (AndroidSupportInjectionModule::class), (ActivityBuildersModule::class)])
interface ApplicationComponent : AndroidInjector<ApplicationClass> {
fun inject(application: Application)
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application?): Builder?
fun build(): ApplicationComponent?
}
}
My activity class:
class MainActivity : DaggerAppCompatActivity() {
@Inject @Named("appInfo") lateinit var appInfo : String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Toast.makeText(this, appInfo, Toast.LENGTH_LONG).show()
}
}
I managed to make it work if I don't use @Named annotation in any of the two dependencies i.e if I delete one of the Two provided dependencies from CoreModule, and remove the @Named annotation from the only dependency left, it will work fine like below:
@Module
class CoreModule {
@Provides
fun appName() : String{
return "Uburu Store"
}
@Provides
@Named("appInfo")
fun appInfo(appName: String) : String {
return "$appName Version:: $"
}
}
//This will work just fine, which made me realize that the @Named must be making it difficult for Dagger to understand something.
The problem with this approach is that I can't do without the @Named as it's needed for Multiple Binding of the same DataTypes e.g: String.
My research so far made it known to me that I have to use @JvmSuppressWildcards somewhere but I'm not sure where.
Upvotes: 0
Views: 444
Reputation: 568
Dagger provides a dependency based on class types in the graph, in your first code snippet of CoreModule it fails to provide dependencies into the appInfo(String, String)
method because it cannot figure out which String type belongs where. The fix is simple; annotate the dependencies that you have already provided with the @Named
qualifier in the method that requires them within the module:
@Module
class CoreModule {
@Provides
@Named("appName")
fun appName() : String{
return "Uburu Store"
}
@Provides
@Named("appVersion")
fun appVersion() : String {
return "0.0.1"
}
@Provides
@Named("appInfo")
fun appInfo(@Named("appName") appName: String, @Named("appVersion") appVersion: String) : String {
return "$appName Version:: $appVersion"
}
}
Your second example works because there is only one String type to be provided from the graph.
For more information head over to the documentation and scroll to Qualifier section
Upvotes: 2