Android Dagger 2 Some Constructors can't Inject into ViewModel
Clash Royale CLAN TAG#URR8PPP
Android Dagger 2 Some Constructors can't Inject into ViewModel
I want to Inject my Room Repositories and Rest Repositories into my ViewModel class. However, I can inject rest repository but, when I try to inject room repository, it gives error.
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()
And error is like that:
error: [dagger.android.AndroidInjector.inject(T)] me.ibrahimsn.capsules.data.local.message.MessageDao cannot be provided without an @Provides-annotated method.
Edit: Solution https://stackoverflow.com/a/51783147/10203775
Inject
RestService
MessageRepository
@nikis when I make like that, it gives error like you should inject constructor method
– mystogan
Aug 9 at 15:40
What is the point of
MessageRepository
and RestRepository
? They literally just forward method calls to DAO / Service. This is called Middleman
and it is a code smell, these classes are not needed. You could use your DAO and your Service directly and get the exact same result with less code.– EpicPandaForce
Aug 9 at 16:31
MessageRepository
RestRepository
Middleman
Repository classes make easier unit testing. So, how should I inject my message repository into my viewmodel? @EpicPandaForce
– mystogan
Aug 9 at 18:03
Why message says "MessageDao cannot be provided"? Something wrong with this? Dagger cannot get MessageDao to provide MessageRepo? Have investigated this?
– Demigod
Aug 10 at 8:19
1 Answer
1
I fixed the problem, thanks..
@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)
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
You don't need
Inject
annotations onRestService
andMessageRepository
, because you create them by yourself in module.– nikis
Aug 9 at 15:03