android - 如何使用 Kodein 为工厂类实例化许多参数
问题描述
我正在Kodein
为我的kotlin
项目注入依赖项。所以我有一个 ViewModel 工厂,如下所示
class ReadViewModelFactory(private val readRepository: ReadRepositoryImpl, private val activity: ReadActivity) : ViewModelProvider.NewInstanceFactory() {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
val guid = activity.intent.getIntExtra(Constants.EXTRA_GUID, 0)
val pubDate = activity.intent.getStringExtra(Constants.EXTRA_DATE)
val title = activity.intent.getStringExtra(Constants.EXTRA_TITLE)
val headImage = activity.intent.getStringExtra(Constants.EXTRA_IMAGE_URL)
val kanal = activity.intent.getStringExtra(Constants.EXTRA_KANAL_READ)
val intentRead = IntentRead(guid, pubDate, title, headImage, kanal)
return ReadViewModel(readRepository, intentRead) as T
}
}
然后,在我的 Application 类中,我创建了:
class App : MultiDexApplication(), KodeinAware{
override val kodein = Kodein.lazy {
import(androidXModule(this@App))
bind() from singleton { NetworkConnectionInterceptor(instance()) }
bind() from singleton { ApiService(instance()) }
bind() from provider { ReadViewModelFactory(instance(),instance())}
}
override fun onCreate() {
super.onCreate()
}
}
如您所见,我的ReadViewModelFactory
. 但是当我运行我的应用程序崩溃发生在ReadActivity
. 什么控制台日志说
java.lang.RuntimeException: 无法启动活动 ComponentInfo{id.my.app/id.my.app.ui.read.ReadActivity}: org.kodein.di.Kodein$NotFoundException: 没有为 bind() 找到绑定? ().? { ? 在这个 Kodein 容器中注册:
我的ReadActivity
样子如下:
class ReadActivity : AppCompatActivity(), KodeinAware{
override val kodein by kodein()
private val factory : ReadViewModelFactory by instance()
.......
}
全栈跟踪
08-21 11:23:54.807 27186-27186/id.my.app E/AndroidRuntime: 致命异常: 主进程: id.my.app, PID: 27186 java.lang.RuntimeException: 无法启动活动 ComponentInfo{id. my.app/id.grid.app.ui.read.ReadActivity}:org.kodein.di.Kodein$NotFoundException:没有找到绑定()与?()的绑定。?{ ? 在这个 Kodein 容器中注册:
解决方案
你的类ReadViewModelFactory
有一个ReadActivity
构造函数参数,它在 Kodein 中没有绑定。
有两种方法可以解决这个问题:
1.使用上下文
因为你是直接在中检索ReadActivity
,所以activity就是上下文,所以你可以绑定上下文:
bind() from contexted<ReadActivity>.provider { ReadViewModelFactory(instance(), context)}
然后,在 中ReadActivity
,您可以像这样检索:
private val factory : ReadViewModelFactory by instance()
但是,在另一个类中,您必须明确指定上下文:
private val factory : ReadViewModelFactory by on(activity).instance()
2.使用工厂
您可以将活动作为参数传递,其优点是在任何地方都具有相同的检索语法:
bind() from factory { activity: ReadActivity -> ReadViewModelFactory(instance(), activity)}
然后,在检索中:
private val factory : ReadViewModelFactory by instance(arg = activity)
推荐阅读
- python - grequests 忽略 ssl 错误
- c++ - 在文本文件中移动 C++
- uicollectionviewcell - 不同的单元格 CollectionView rxswift
- image - 使用 matplotlib 绘制的图像似乎具有与原始 JPEG 图像不同的颜色
- python - 具有自定义分隔符和新列名的列表变量的 One-hot 编码
- javascript - 当我查询 API 时,JSON 中位置 0 的意外标记 O
- salt-stack - 如何使用 Salt 中的管理员权限在 Windows 中运行 cmd
- deep-learning - 如何在 pytorch 中将多个灰度图像作为单个张量加载?
- javascript - 导入/要求 JSON 文件作为克隆到 Vue 数据属性中
- python - 为什么打印的整数中间有空格?