android - 如果没有 @Provides 方法,则无法提供 Dagger 2 Named

标签 android dependency-injection kotlin dagger-2

尝试深入了解 Dagger 2 并遇到命名提供程序的问题。我有一个简单的设置如下:

// Module
@Module
class AppModule(private val app: App) {
    @Provides @AppScope fun providesApp() = app

    @Provides @AppScope fun provideSharedPreferences(app: App) = PreferenceManager.getDefaultSharedPreferences(app)

    @Provides @AppScope @Named("Uri1") fun providesUri1() = Uri.Builder().scheme("https").authority("authory1").build()

    @Provides @AppScope @Named("Uri2") fun providesUri2() = Uri.Builder().scheme("https").authority("authory2").build()
}

// Component
@AppScope
@Component(modules = arrayOf(AppModule::class))
interface AppComponent {
    fun inject(target: MainActivity)
}

// MainActivity
@Inject @AppScope lateinit var preferences: SharedPreferences
@Inject @AppScope @Named("Uri1") lateinit var uri1: Uri
@Inject @AppScope @Named("Uri2") lateinit var uri2: Uri

当我重建我的项目时:

Error:Gradle: android.net.Uri cannot be provided without an @Provides- or @Produces-annotated method.

我不明白为什么在这里添加 Named 限定符对我不起作用。如果我删除这些,我可以毫无问题地获得 SharedPreferences 的实例。

任何关于我做错了什么的见解将不胜感激!

编辑:

根据建议进行更改,结果与上述相同。

// New module
@Module
class AppModule(private val app: App) {
    @Provides @AppScope fun providesApp() = app

    @Provides @AppScope fun provideSharedPreferences(app: App) = PreferenceManager.getDefaultSharedPreferences(app)

    @Provides @AppScope @Tag("Uri1") fun providesUri1(): Uri = Uri.Builder().scheme("https").authority("authority1").build()

    @Provides @AppScope @Tag("Uri2") fun providesUri2(): Uri = Uri.Builder().scheme("https").authority("authority2").build()
}

// Tag annotation
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class Tag(val tag: String = "")

// MainActivity
@Inject @AppScope lateinit var preferences: SharedPreferences
@Inject @AppScope @Tag("Uri1") lateinit var uri1: Uri
@Inject @AppScope @Tag("Uri2") lateinit var uri2: Uri

Project Repo @ Github

最佳答案

我想我发现了问题(至少我检查了你的项目并且它正确地生成了 Dagger 类)。如果您需要注入(inject)带有 @Named 或一些 @Qualifier 注释的字段,则必须使用这种语法:

class MainActivity : AppCompatActivity() {
    @Inject lateinit var preferences: SharedPreferences
    @Inject @field:[Named ("Uri1")] lateinit var uri1: Uri // for @Named annotation or...
    @Inject @field:Uri2 lateinit var uri2: Uri // ...for @Qualifier annotation

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        app().component.inject(this)

        println(uri1)
        println(uri2)
    }
}

注意 @Named/限定符注释如何进入 @field: (没有 @ 本身)。

repo 借来的想法.

关于android - 如果没有 @Provides 方法,则无法提供 Dagger 2 Named,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36199796/

相关文章:

Android RecyclerView : Update all items height after notifyDataSetChanged

Android - 如何将 JSON 对象添加到 sharedPreferences?

asp.net-mvc - 每个 Web 请求的 EF DbContext + Custom RoleProvider = 每个 Web 请求或单例的 RoleProvider?

android - 如何使用 Kotlin 访问 LiveData<List<MVoice>> 的每个元素?

java - 我想在 kotlin 中为我的自定义 ImageView 添加圆角

android - 使用 google mlkit 视觉样本减少跟踪窗口

android - AWS Cognito - 获取带 ID 的用户信息

android - Android中一个线程可以重复使用吗?

dependency-injection - 我的工厂对象是否引入了全局状态?

c# - 基于基本泛型类型调用正确的泛型接口(interface)实现