I am confused by many different ways in ZIO to do what seems to be the same thing (at least to my noobie eye).
In particular, something like this:
val layer: RLayer[ServiceA with ServiceB, ServiceC] = ZLayer.scoped {
for {
a <- ZIO.service[ServiceA]
b <- ZIO.service[ServiceB]
} yield new ServiceCImpl(a, b)
}
vs
val layer2: RLayer[ServiceA with ServiceB, ServiceC] = ZLayer.fromZIO {
for {
a <- ZIO.service[ServiceA]
b <- ZIO.service[ServiceB]
} yield new ServiceCImpl(a, b)
}
Are these two snippets doing the same thing? If not, what is the difference? If yes, why are there two of them? When would you use one over the other?
In your case, they are doing the same thing. And there's actually a 3rd way with
ZLayer.fromFunction
:Which is IMHO the simplest.
What is the difference then?
ZLayer.scoped
is to be used when the service you're creating needs some scoped resources (like opening a file and closing it automatically when "stopping" the service, or a database connection)ZLayer.fromZIO
is to be used when there's no resource to manage but still there are potential errors and creating the service is represented as aZIO
ZLayer.fromFunction
is to be used when none of the above apply, that is when creating the service just needs some other dependencies but it cannot fail and doesn't need to manage any resourceSee also ZLayer reference documentation.