我希望我的应用程序具有以下体系结构:
-di // dependancy injection package
-model
--datasources // implementations of repositories, using dao to return data
--dao // access to the database (room)
--repositories // interfaces
-ui // activities, fragments...
-viewmodels // viewmodels of each fragment / activity which will return data to the views in the ui package
在Android上,人们似乎通常在活动中进行依赖注入,但是我想将我的存储库注入到视图模型中。
我有一个使用手动创建的LiveData的特定视图模型
class NavigationViewModel(application: Application) : AndroidViewModel(application) {
init {
DaggerAppComponent.builder()
.appModule(AppModule(getApplication()))
.roomModule(RoomModule(getApplication()))
.build()
.injectNavigationViewModel(this)
}
@Inject
lateinit var displayScreenRepository: DisplayScreenRepository
fun setScreenToDisplay(screen: DisplayScreen) {
displayScreenRepository.setScreenToDisplay(screen)
}
}
在我的RoomModule中,我有此提供程序:
@Singleton
@Provides
internal fun displayScreenRepository(): DisplayScreenRepository {
return DisplayScreenDataSource()
}
DisplayScreenDataSource类非常简单:
class DisplayScreenDataSource : DisplayScreenRepository {
private val screenToDisplay = MutableLiveData<DisplayScreen>()
override fun getScreenToDisplay(): LiveData<DisplayScreen> {
return screenToDisplay
}
override fun setScreenToDisplay(screen: DisplayScreen) {
if (Looper.myLooper() == Looper.getMainLooper()) {
screenToDisplay.value = screen
} else {
screenToDisplay.postValue(screen)
}
}
}
我希望此单例可用于其他视图模型MainActivityViewModel,所以我这样做了:
class MainActivityViewModel(application: Application) : AndroidViewModel(application) {
@Inject
lateinit var displayScreenRepository: DisplayScreenRepository
init {
DaggerAppComponent.builder()
.appModule(AppModule(application))
.roomModule(RoomModule(application))
.build()
.injectMainViewModel(this)
}
}
但是,当我运行我的应用程序时,实例化的存储库没有相同的引用,并且当我更新其中一个ViewModel中一个LiveData的值时,如果我观察到另一个ViewModel的LiveData,则不相同LiveData不会更新。
我的猜测是我不正确地实例化了DaggerAppComponent:它应该只创建一次,并最终注入多次。 是吗?
我应该在哪里存储DaggerAppComponent的实例?在应用程序类中?
我可能会有这样的东西:
class MainActivityViewModel(application: Application) : AndroidViewModel(application) {
@Inject
lateinit var displayScreenRepository: DisplayScreenRepository
init {
(application as MyApplication).daggerAppComponent.injectMainViewModel(this)
}
}
这是推荐的方法吗?