【问题标题】:Dependency injection using hilt on singleton private constructor class在单例私有构造函数类上使用 hilt 进行依赖注入
【发布时间】:2021-07-30 20:27:20
【问题描述】:

我是新手。所以我想在我的使用 MVVM 架构的项目上尝试依赖注入。 结构如下所示:JsonHelper -> RemoteDataSource -> Repository -> ViewModel。

当我尝试在 RemoteDataSource 和 Repository 上注入我的 DI 时会出现问题,因为这些类是单例类并且具有私有构造函数。 错误代码如下所示

..location\RemoteDataSource.java:40: error: Dagger does not support injection into Kotlin objects
public static final class Companion {

..location\Repository.java:30: error: Dagger does not support injection into Kotlin objects
public static final class Companion {

这些是我的 RemoteDataSource 和 Repository 代码,我尝试将它注入构造函数,但它说 Dagger 不能注入私有构造函数,所以我尝试将它注入函数但仍然没有工作

RemoteDataSource.kt

@Singleton
class RemoteDataSource private constructor(private val jsonHelper: JsonHelper) {

companion object {

    @Volatile
    private var instance: RemoteDataSource? = null

    @Inject
    fun getInstance(jsonHelper: JsonHelper): RemoteDataSource =
        instance ?: synchronized(this) {
            instance ?: RemoteDataSource(jsonHelper).apply { instance = this }
        }

}

fun getAllRemoteMovies(moviesCallback: LoadMoviesCallback) {
    moviesCallback.onAllMoviesReceived(jsonHelper.loadRemoteMovies())
}

fun getAllRemoteTVShows(tvshowCallback: LoadTVShowCallback) {
    tvshowCallback.onAllTVShowsReceived(jsonHelper.loadRemoteTVShows())
}

interface LoadMoviesCallback {
    fun onAllMoviesReceived(moviesResponses: ArrayList<MovieItem>)
}

interface LoadTVShowCallback {
    fun onAllTVShowsReceived(tvshowResponses: ArrayList<TVShowItem>)
}

}

Repository.kt

@Singleton
class Repository private constructor(private val remoteDataSource: RemoteDataSource) : DataSource {

companion object {

    @Volatile
    private var instance: Repository? = null

    @Inject
    fun getInstance(remoteDataSource: RemoteDataSource): Repository =
        instance ?: synchronized(this) {
            instance ?: Repository(remoteDataSource).apply { instance = this }
        }

}

override fun getAllRemoteMovies(): LiveData<ArrayList<MovieItem>> {
    val remoteMoviesResult = MutableLiveData<ArrayList<MovieItem>>()
    remoteDataSource.getAllRemoteMovies(object : RemoteDataSource.LoadMoviesCallback {
        override fun onAllMoviesReceived(moviesResponses: ArrayList<MovieItem>) {
            remoteMoviesResult.value = moviesResponses
        }
    })
    return remoteMoviesResult
}

override fun getAllRemoteTVShows(): LiveData<ArrayList<TVShowItem>> {
    val remoteTVShowsResult = MutableLiveData<ArrayList<TVShowItem>>()
    remoteDataSource.getAllRemoteTVShows(object : RemoteDataSource.LoadTVShowCallback {
        override fun onAllTVShowsReceived(tvshowResponses: ArrayList<TVShowItem>) {
            remoteTVShowsResult.value = tvshowResponses
        }
    })
    return remoteTVShowsResult
}

}

这是我的注入模块 RemoteDataSourceModule.kt

@Module
@InstallIn(ActivityComponent::class)
object RemoteDataSourceModule {

@Singleton
@Provides
fun provideJsonHelper(context: Context): JsonHelper {
    return JsonHelper(context)
}

@Singleton
@Provides
fun provideRemoteDataSource(jsonHelper: JsonHelper): RemoteDataSource {
    return RemoteDataSource.getInstance(jsonHelper)
}

@Singleton
@Provides
fun provideRepository(remoteDataSource: RemoteDataSource): Repository {
    return Repository.getInstance(remoteDataSource)
}

}

那么如何在不将类构造函数更改为 public 的情况下解决这个问题呢?

【问题讨论】:

  • 正如错误所说,您不能注入 Kotlin 对象。也没有必要,你可以用 Hilt 指定单例。
  • @HenryTwist 哦,是的,我很笨,谢谢你的回答

标签: android kotlin dependency-injection dagger-hilt


【解决方案1】:

@Singleton 注释足以通知该类是单例类,所以我只需删除伴随对象并使用公共构造函数更改私有构造函数,因此代码将如下所示:

@Singleton
class RemoteDataSource @Inject constructor(private val jsonHelper: JsonHelper) {
    // Your codes
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    相关资源
    最近更新 更多