Koin: How to inject a generic type?

Created on 29 May 2019  路  7Comments  路  Source: InsertKoinIO/koin

I am new to Koin as I am trying to move my code from Dagger 2 to Koin. I have MVP architecture android project. With Dagger 2 I used to have a class like this:

abstract class BaseActivity<V : BaseView, P : BasePresenter<V>> :
        MvpActivity<V, P>(), BaseView, HasSupportFragmentInjector {

    @Inject
    lateinit var fragmentInjector: DispatchingAndroidInjector<Fragment>

    @Inject
    lateinit var mPresenter: P

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
    }
...
}

As you can see presenter is generic type here. Which works fine with Dagger 2.

I want to know how I can achieve this in Koin.

I tried private var mPresenter: P by inject<P>() and private var mPresenter: P = get<P>()
Both shows error.

All 7 comments

Sounds like a duplicate of #75

You could use named named bindings to inject generics.

The problem in your case is that you have the presenter as a type parameter P,
so using named will not work. Have you thought about moving the injection of the presenter in your Activity subclasses?

@cortinico Currently I have moved it to subclasses so that it can work. But thats just boiler plate code. I wish it could work in Base Class only.

Yeah I know, but I don't think that's possible to do what you want to do with Koin due to how Generics works (see type erasure).

Even I which this feature existed in Koin.

@cortinico Can you check the change log for Kotlin 1.3.40. https://blog.jetbrains.com/kotlin/2019/06/kotlin-1-3-40-released/

There is some improvement in generic type.

Accessing the reified type using reflection on JVM
Another experimental function added in this release is the typeOf function. At a glance, you can use it to construct an instance of KType for a given type

abstract class BaseUseCase<R : BaseRepository> : KoinComponent {
    private val _repository: BaseRepository by inject()
    protected val repository: R
        get() {
            return _repository as R
        }
}

this works fore me

@robertlevonyan it's not work for me

LoginRepository extends BaseRepository

factory<BaseRepository> { LoginRepository(get()) }

abstract class BaseUseCase<R : BaseRepository> : KoinComponent {
    private val _repository: BaseRepository by inject()
    protected val repository: R
        get() {
            return _repository as R
        }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

LukasAnda picture LukasAnda  路  3Comments

sankarsana picture sankarsana  路  4Comments

haroldadmin picture haroldadmin  路  3Comments

iRYO400 picture iRYO400  路  3Comments

mubarak1361 picture mubarak1361  路  3Comments