ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ZLayer module pattern 을 이용한 dependency injection
    zio/zio1 2021. 8. 18. 17:44

    문제

    zio module pattern 1.0 은 쓸데없이 복잡해 차라리 constructor dependency injection 을 쓰는게 낫다고 생각해 왔다. zio module pattern 2.0 이 최근에 소개되었는데, zio magic 과 함께 쓰면 어느정도 쓸만한 것 같다.

     

    코드

    import zio.clock.Clock
    import zio.console.Console
    import zio.magic._
    import zio.{ App, ExitCode, Has, Ref, UIO, URIO, URLayer, ZIO, ZLayer }
    
    object ZLayerTest extends App {
      trait Logging {
        def log(line: String): UIO[Unit]
      }
    
      object Logging {
        // URIO 가 아닌 ZStream 일 경우 ZIO.serviceWith 대신에
        // ZStream.accessStream(_.get.XXX) 사용
        def log(line: String): URIO[Has[Logging], Unit] = 
          ZIO.serviceWith[Logging](_.log(line))
    
        val refLayer: ZLayer[Any, Nothing, Has[Ref[Long]]] = Ref.make(0L).toLayer
        val fullLayer: URLayer[Has[Console.Service] with Has[Clock.Service] with Has[Ref[Long]], Has[Logging]] =
          LoggingLive.toLayer[Logging]
    
        val live: ZLayer[Has[Console.Service] with Has[Clock.Service], Nothing, Has[Logging]] =
          ZLayer.wireSome[Has[Console.Service] with Has[Clock.Service], Has[Logging]](refLayer, fullLayer)
      }
    
      case class LoggingLive(console: Console.Service, clock: Clock.Service, ref: Ref[Long]) extends Logging {
        override def log(line: String): UIO[Unit] =
          for {
            current <- clock.currentDateTime.orDie
            count   <- ref.modify(x => (x + 1, x + 1))
            _       <- console.putStrLn(current.toString + s": [$count] " + line).orDie
          } yield ()
      }
    
      override def run(args: List[String]): URIO[zio.ZEnv, ExitCode] = {
        val program: URIO[Has[Logging], Unit] = Logging.log("Hi") *> Logging.log("Hello")
        program.injectSome[zio.ZEnv](Logging.live).exitCode
      }
    }

     

    출력 결과 샘플

    2021-08-19T01:10:28.234+09:00: [1] Hi
    2021-08-19T01:10:28.257+09:00: [2] Hello

    댓글

Designed by Tistory.