Injecting generics with Toothpick DI

329 views Asked by At

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!

1

There are 1 answers

1
Nilzor On BEST ANSWER

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.