Scala Cats Effect Wrapping an Implementation from the Effect Type of the Enclosing Class

98 Views Asked by At

I have an implementation that looks like this:

final class MyServiceImpl[M[_]: Async](dbCfg: DBConfig)(implicit ec: Scheduler) extends MyService[M] {
  ......
  ......
  ......
  ......
}

Inside this class I have some methods that uses doobie to run sql queries against the database. As I was testing them, I felt the need to log these queries and doobie has a nice way to get this done which is to implement the trait LogHandler[M[_]]

I can then have this inside MyServiceImpl like this as stated from doobie's documentation:

val printSqlLogHandler: LogHandler[IO] = new LogHandler[IO] {
  def run(logEvent: LogEvent): IO[Unit] = 
    IO { 
      println(logEvent.sql)
    }
}

That example uses IO, but I would prefer to use the effect type that MyServiceImpl gets instantiated with. How can I do this?

1

There are 1 best solutions below

3
Damoon Salatian On

At first create class like follow:

trait MyLogHandler[M[_]] {
  def log(logEvent: LogEvent): M[Unit]
}

Secondly impeliment to your class:

class MyCustomLogHandler[M[_]: Async] extends LogHandler[M] with MyLogHandler[M] {
  def log(logEvent: LogEvent): M[Unit] =
    Async[M].delay {
      println(logEvent.sql)
    }
}

at the end you can use it like follow:

final class MyServiceImpl[M[_]: Async](dbCfg: DBConfig)(implicit ec: Scheduler) extends MyService[M] {

  val logHandler: LogHandler[M] = new MyCustomLogHandler[M]

  // ...
}