Reputation: 1546
I heve base class and I would like to use Koin injection on this base class like:
abstract class BasePresenterFragment<T : BasePresenter> : BaseFragment() {
lateinit var presenter: T by inject<T>() // here is problem
override fun onStart() {
super.onStart()
presenter.subscribe()
}
override fun onStop() {
super.onStop()
presenter.unSubscribe()
}
}
I know there are solutions for inject viewModel but not for simple injection. So is there any way to use Koin injection with generic type?
Upvotes: 3
Views: 4105
Reputation: 4406
the short answer is Yes
if you have generic classes like this :
the interface :
interface UseCase<Input, Output> {
suspend operator fun invoke(input: Input): Output
}
class implement interface :
class UpdateMovieUseCase internal constructor(
private val repository: MovieRepository
) : UseCase<MovieDomainModel, Unit> {
override suspend fun invoke(movie: MovieDomainModel) =
repository.update(movie.toData())
}
then you can provide a module in KOIN like this :
val domainModule = module {
singleOf(::UpdateMovieUseCase) { bind<UseCase<MovieDomainModel, Unit>>() }
}
source code : https://github.com/Adnan9011/movie_archive
Upvotes: 2
Reputation: 1120
Koin does not support generics by default.
"Koin definitions doesn't take in accounts generics type argument."
however you are supposed to you the named argument to workaround this:
The latest Version even supports directly passing the type insted of a custom string:
module {
single(named<Int>) { ArrayList<Int>() }
single(named<String>) { ArrayList<String>() }
}
and when injecting, simply use get(named<Int>)
or get(named<String>)
depending on your need. For more information cf.: https://insert-koin.io/docs/reference/koin-core/definitions/
Upvotes: 1
Reputation: 1546
Well, I've found only partly solution for this question. It's use presenter like abstract val in base class. This will make it possible to use the methods of presenter in the base class but I still should use inject()
in every subclasses for initialization. Example:
abstract class BasePresenterFragment<P : BasePresenter> : BaseFragment() {
abstract val presenter: P
override fun onStart() {
super.onStart()
presenter.subscribe()
}
override fun onStop() {
super.onStop()
presenter.unSubscribe()
}
}
And subclass:
class HomeFragment : BasePresenterFragment<HomeContract.Presenter>(), HomeContract.View {
...
override val presenter: HomeContract.Presenter by inject()
...
}
Upvotes: 4