首页 > 解决方案 > 使用 Toothpick DI 注入仿制药

问题描述

我一直在玩 ToothPick DI,我遇到了一种情况,我需要向演示者注入几个泛型,但我不知道该怎么做,或者是否有可能。这是我正在尝试做的一个例子。

这是演示者的示例:

@InjectConstructor
class MyPresenter(
    private val interactor1: Interactor1,
    private val interactor2: Interactor2,
    private val issuesList: List<Issue>,
    private val navigator: Page<Parameter>) {

    ......

}

让我们假设interactor1 和interactor2 通过注解或模块正确注入,但是List 和Page 仍然缺少绑定。

class MyActivity: Activity {
    
    private val listOfIssues: List<Issue> = ...
    private val navigationPage: Page<Parameter> = ....

    @Override fun onCreate(savedInstanceState: Bundle?) {
        Toothpick.openRootScope()
           .openSubScope(this)
           .installModules(module {
               bind(??).toInstance(listOfIssues)
               bind(??).toInstance(navigationPage)
           })
    }
}

根据我的经验,我无法将PageList与 Toothpick 绑定,因为它无法注入泛型类型,我错了吗?

谢谢!

标签: androidgenericsdependency-injectiontoothpick-di

解决方案


你是对的,Toothpick 不能注入泛型类型。解决方案是使用命名绑定或包装泛型。

假设您有两个列表 - 一个String类型和一个Int类型。你可以这样做:

命名绑定

// Binding
bind<List<*>>().withName("String").toInstance(yourStringList)
bind<List<*>>().withName("Int").toInstance(yourIntList)

// Usage
@Inject
@field:Named("Int")
lateinit var intList: List<Int>

@field:Named("String")
@Inject
lateinit var stringList: List<String>

包装

class IntList : List<Int> by listOf()
class StringList : List<String> by listOf()

bind<IntList>().toInstance(yourIntList)
bind<StringList>().toInstance(yourStringList) 

@Inject
lateinit var intList: IntList

@Inject
lateinit var stringList: StringList

这更像是一种解决方法,但它可能是一个很好的解决方案

在我使用的两个示例toInstace中,您当然可以自由选择其他绑定方法。


推荐阅读