Home > other >  No ClassTag Avaliable for Trait / Abstract Class
No ClassTag Avaliable for Trait / Abstract Class

Time:08-12

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:

  1. SiteCategoriesExtractorWorker should not be aware of actorReplyClassTag
  2. type ActorReply is used on aggregator package as asInstanceOf[ActorReply]
  3. actorReplyClassTag is used on messageAdapter (https://doc.akka.io/japi/akka/current/akka/actor/typed/scaladsl/ActorContext.html#messageAdapter(scala.Function1,scala.reflect.ClassTag)
  4. 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]]
}
  • Related