首页 > 解决方案 > 如何使用 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 容器中注册:

标签: androidkotlinmvvmdependency-injectionkodein

解决方案


你的类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)

推荐阅读