Tofasio
Tofasio

Reputation: 425

Injecting generics with Toothpick DI

I've been playing around with ToothPick DI and I'm on a situation where I need to inject a couple of generics to a presenter and I don't know how to do it, or if it's even possible. Here's an example of what I'm trying to do.

This is an example of presenter:

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

    ......

}

Let's imagine that interactor1 and interactor2 are correctly injected via annotations or modules, but the List and the Page are still missing to bind.

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)
           })
    }
}

In my experience I cannot bind Page or List with Toothpick as it cannot inject generic types, am I wrong?

Thanks!

Upvotes: 0

Views: 400

Answers (1)

Nilzor
Nilzor

Reputation: 18593

You're correct that Toothpick can't inject generic types. The solution would be to used named bindings or to wrap the generics.

Let's say you have two lists - one of String type and one of Int type. Here's how you could do it:

Named bindings

// 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>

Wrapping

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

This is more of a workaround but it might be a good solution nevertheless

In both examples I use toInstace but you are of course free to choose other binding methods.

Upvotes: 1

Related Questions