Hi, I have these interfaces:
interface Query<T>
interface QueryHandler<in TQuery, TResult : Any> where TQuery : Query<TResult> {
fun execute(query: TQuery): TResult
}
and dispatcher:
abstract class QueryDispatcher {
abstract fun <TQuery, TResult : Any> dispatch(query: TQuery, queryType: KClass<TQuery>, resultType: KClass<TResult>): TResult where TQuery : Query<TResult>
inline fun <reified TQuery, reified TResult : Any> dispatch(query: TQuery) where TQuery : Query<TResult> =
dispatch(query, TQuery::class, TResult::class)
}
class InMemoryQueryDispatcher(
private val applicationContext: GenericWebApplicationContext
) : QueryDispatcher() {
override fun <TQuery : Query<TResult>, TResult : Any> dispatch(query: TQuery, queryType: KClass<TQuery>, resultType: KClass<TResult>): TResult {
val beanFactory = applicationContext.beanFactory
val resolvableType = ResolvableType.forClassWithGenerics(QueryHandler::class.java, queryType.java, resultType.java)
val beans = applicationContext.getBeanNamesForType(resolvableType)
val handler = beanFactory.getBean<QueryHandler<TQuery, TResult>>(beans.first())
...
}
}
This handler implementation with non-generic TResult
works:
class GetUserHandler() : QueryHandler<GetUser, UserDto> { ... }
but when I use another generic there:
class GetUsersHandler() : QueryHandler<GetUsers, List<UserDto>> { ... }
Spring cannot find my handler bean.
My findings:
ResolvableType.forClassWithGenerics()
produces ResolvableType
QueryHandler<GetUsers, List<?>>
, so when Spring iterates through all beans and checks the one I am looking for, ResolvableType::isAssignableFrom
matches QueryHandler
, then GetUsers
, then List
and fails on matching ?
with UserDto
- this condition returns false.
I don’t know if I am doing something wrong or if there is some problem (either bug or language limitation?)
So, don’t you by any chance know if this is this somehow possible?
Thank you!