【问题标题】:Android Dagger 2 Some Constructors can't Inject into ViewModelAndroid Dagger 2 一些构造函数无法注入到 ViewModel
【发布时间】:2018-08-09 14:36:35
【问题描述】:

我想将我的 Room Repositories 和 Rest Repositories 注入到我的 ViewModel 类中。但是,我可以注入 rest 存储库,但是当我尝试注入 room 存储库时,它会出错。

class RestRepository @Inject constructor(private val restService: RestService) {
    fun register(username: String, password: String, email: String): Single<NormalResponse> {
        return restService.register(username, password, email)
    }

    fun createAuthToken(username: String, password: String): Single<TokenResponse> {
        return restService.createAuthToken(username, password)
    }
}

class MessageRepository @Inject constructor(private val messageDao: MessageDao) {
    val all: List<Message> get() = messageDao.getAll

    fun insert(vararg messages: Message) {
        messageDao.insert(*messages)
    }

    fun update(message: Message) {
        messageDao.update(message)
    }

    fun delete(message: Message) {
        messageDao.delete(message)
    }
}

@Module
class RestModule {
    @Provides
    internal fun provideRetrofit(): Retrofit {
        return Retrofit.Builder()
                .baseUrl(Constants.BASE_URL)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()
    }

    @Provides
    internal fun provideService(retrofit: Retrofit): RestService {
        return retrofit.create<RestService>(RestService::class.java)
    }

    @Provides
    internal fun provideRepository(restService: RestService): RestRepository {
        return RestRepository(restService)
    }
}

@Module(includes = [ApplicationModule::class])
class RoomModule {
    @Provides
    internal fun provideRoomDatabase(context: Context): AppDatabase {
        return AppDatabase.getAppDatabase(context)
    }

    @Provides
    internal fun provideMessageDao(appDatabase: AppDatabase): MessageDao {
        return appDatabase.messageDao()
    }

    @Provides
    internal fun provideMessageRepository(messageDao: MessageDao): MessageRepository {
        return MessageRepository(messageDao)
    }
}

@Module
abstract class MainFragmentBindingModule {
    @ContributesAndroidInjector(modules = [ApplicationModule::class, UtilsModule::class, RestModule::class, RoomModule::class])
    internal abstract fun provideChatFragmentFactory(): ChatFragment
}

class ChatViewModel @Inject constructor(val restRepository: RestRepository, val messageRepository: MessageRepository) : ViewModel() {

}

错误是这样的:

错误:[dagger.android.AndroidInjector.inject(T)] me.ibrahimsn.capsules.data.local.message.MessageDao 不能在没有@Provides-annotated 方法的情况下提供。

编辑:解决方案https://stackoverflow.com/a/51783147/10203775

【问题讨论】:

  • RestService 和MessageRepository 上不需要Inject 注释,因为您在模块中自己创建它们。
  • @nikis 当我这样做时,它会给出错误,就像你应该注入构造函数方法
  • MessageRepository 和RestRepository 的意义何在?他们实际上只是将方法调用转发给 DAO / Service。这称为Middleman,这是一种代码味道,不需要这些类。您可以直接使用您的 DAO 和您的服务,并使用更少的代码获得完全相同的结果。
  • 存储库类使单元测试更容易。那么,我应该如何将我的消息存储库注入到我的视图模型中? @EpicPandaForce
  • 为什么消息说“无法提供MessageDao”?这有什么问题吗? Dagger 无法获取 MessageDao 提供 MessageRepo?对此进行过调查吗?

标签: android dependency-injection kotlin viewmodel dagger-2


【解决方案1】:

我解决了这个问题,谢谢..

@Module(includes = [(ViewModelModule::class)])
class ApplicationModule {

    @Provides
    @Singleton
    internal fun provideRetrofit(): Retrofit {
        return Retrofit.Builder()
                .baseUrl(Constants.BASE_URL)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()
    }

    @Provides
    @Singleton
    internal fun provideRetrofitService(retrofit: Retrofit): RestService {
        return retrofit.create<RestService>(RestService::class.java)
    }

    @Provides
    @Singleton
    internal fun provideRoomDatabase(app: Application): AppDatabase {
        return AppDatabase.getAppDatabase(app)
    }

    @Provides
    @Singleton
    internal fun provideMessageDao(appDatabase: AppDatabase): MessageDao {
        return appDatabase.messageDao()
    }
}

@Singleton
class MessageRepository @Inject constructor(private val messageDao: MessageDao) {

    val all: List<Message> get() = messageDao.getAll

    fun insert(vararg messages: Message) {
        messageDao.insert(*messages)
    }

    fun update(message: Message) {
        messageDao.update(message)
    }

    fun delete(message: Message) {
        messageDao.delete(message)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 2019-02-23
    • 2018-06-08
    • 2017-12-24
    相关资源
    最近更新 更多