Consider the following trait:
trait Aggregatable[Command] {
protected[aggregator] type ActorReply
protected[aggregator] val actorReplyClassTag: ClassTag[ActorReply]
... // Additional Implementation
}
then, the following abstract class:
abstract class AsyncWorker[Request, Reply] extends Aggregatable[AsyncWorkerRequest[Request, Reply]] {
override final type ActorReply = AsyncWorkerReply[Request, Reply]
override protected val actorReplyClassTag: ClassTag[AsyncWorkerReply[Request, Reply]] = ???
... // Additional Implementation
}
and then the concrete implementation:
class SiteCategoriesExtractorWorker extends AsyncWorker[SiteCategoriesRequest, SiteCategoriesReply]
The problem is that I cannot initialize actorReplyClassTag properly.
The desired solution should:
- SiteCategoriesExtractorWorker should not be aware of actorReplyClassTag
- type ActorReply is used on
aggregator
package asasInstanceOf[ActorReply]
- actorReplyClassTag is used on
messageAdapter
(https://doc.akka.io/japi/akka/current/akka/actor/typed/scaladsl/ActorContext.html#messageAdapter(scala.Function1,scala.reflect.ClassTag) - Aggregatable is preferred to be a trait rather then abstract class
Note: I'm using reflection in order to make some generic aggregation over Aggregatable interface.
Any ideas how to achieve this?
CodePudding user response:
You just need to pass class tags of the parameters down to AsyncWorker
, then class tag will be available implicitly:
class AsyncWorker[Request : ClassTag, Reply : ClassTag] extends Aggregatable[AsyncWorkerRequest[Request, Reply]] {
type ActorReply = AsyncWorkerReply[Request, Reply]
val actorReplyClassTag: ClassTag[ActorReply] = implicitly[ClassTag[ActorReply]]
}