我正在學習 ZIO 2.x,Runtime使用bootstrap層配置時,它不起作用。
object RuntimeCustom extends ZIOAppDefault {
// It's not work, And I don't know why?
override val bootstrap = EmailService.live
def run = (for {
_ <- ZIO.debug("Start...")
_ <- EmailService.send("God", "Hi")
_ <- ZIO.debug("End...")
} yield ())
}
得到一個錯誤:
[error] /Users/changzhi/github-repo/zio-start/src/main/scala/zio/reference/experiment/core/RuntimeCustom.scala:35:7:
[error]
[error] ──── ZIO APP ERROR ───────────────────────────────────────────────────
[error]
[error] Your effect requires a service that is not in the environment.
[error] Please provide a layer for the following type:
[error]
[error] 1. example.EmailService
[error]
[error] Call your effect's provide method with the layers you need.
[error] You can read more about layers and providing services here:
[error]
[error] https://zio.dev/next/datatypes/contextual/
[error]
[error] ──────────────────────────────────────────────────────────────────────
[error]
[error] _ <- EmailService.send("God", "Hi")
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
如果我用 替換provide,它可以作業。
object RuntimeCustom extends ZIOAppDefault {
def run = (for {
_ <- ZIO.debug("Start...")
_ <- EmailService.send("God", "Hi")
_ <- ZIO.debug("End...")
} yield ())
// This can works, have no doubt
.provide(EmailService.live)
}
完整版程式在這里
package example
import zio._
trait EmailService {
def send(user: String, content: String): Task[Unit]
}
object EmailService {
def send(user: String, content: String): ZIO[EmailService, Throwable, Unit] =
ZIO.serviceWithZIO[EmailService](_.send(user, content))
val live: ZLayer[Any, Nothing, EmailService] =
ZLayer.fromZIO( ZIO.succeed(EmailServiceFake()) <* Console.printLine("Init EmailService") ).orDie
}
case class EmailServiceFake() extends EmailService {
override def send(user: String, content: String): Task[Unit] =
Console.printLine(s"sending email to $user")
}
object RuntimeCustom extends ZIOAppDefault {
// It's not work, And I don't know why?
//override val bootstrap = EmailService.live
def run = (for {
_ <- ZIO.debug("Start...")
_ <- EmailService.send("God", "Hi")
_ <- ZIO.debug("End...")
} yield ())
// This can works, have no doubt
.provide(EmailService.live)
}
uj5u.com熱心網友回復:
ZIOAppDefault適用于不需要額外服務的應用程式,假設它們只會“需要”內置服務,因為您已經使用該方法提供了其他要求。provide
如果您想使用該bootstrap方法,您應該擴展ZIOApp并覆寫environmentTagandEnvironment欄位,以便該run機制知道如何構造最終環境。
import zio._
object App extends ZIOApp {
// Tell ZIO how the environment is constructed
override val environmentTag: EnvironmentTag[Environment] = EnvironmentTag[Environment]
// Tell the app which layers will be leftover from the `run`
override type Environment = FooService
// The app how to construct those remaining layers
override val bootstrap = FooService.layer
val run = FooService.doFoo
}
class FooService {
def doFoo: UIO[Unit] = ZIO.unit
}
object FooService {
val layer = ZLayer.succeed(new FooService)
def doFoo = ZIO.serviceWithZIO[FooService](_.doFoo)
}
編輯
使用原始示例來證明這是有效的:
import zio._
trait EmailService {
def send(user: String, content: String): Task[Unit]
}
object EmailService {
def send(user: String, content: String): ZIO[EmailService, Throwable, Unit] =
ZIO.serviceWithZIO[EmailService](_.send(user, content))
val live: ZLayer[Any, Nothing, EmailService] =
ZLayer.fromZIO( ZIO.succeed(EmailServiceFake()) <* Console.printLine("Init EmailService") ).orDie
}
case class EmailServiceFake() extends EmailService {
override def send(user: String, content: String): Task[Unit] =
Console.printLine(s"sending email to $user")
}
object RuntimeCustom extends ZIOApp {
// It's not work, And I don't know why?
override val bootstrap = EmailService.live
override type Environment = EmailService
override val environmentTag: EnvironmentTag[Environment] = EnvironmentTag[Environment]
def run = (for {
_ <- ZIO.debug("Start...")
_ <- EmailService.send("God", "Hi")
_ <- ZIO.debug("End...")
} yield ())
}
https://scastie.scala-lang.org/02MMaWS2S6Wwe55a24H7Sg
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/512168.html
標籤:斯卡拉运行层齐奥
上一篇:scala-map&flatten顯示與flatMap不同的結果
下一篇:Scala-根據行數拆分資料幀
