Conversation
|
One more naming idea: |
|
@adamw actually in this case |
|
Hmm well but Another candidate: |
|
And yes, sure, we do want to support instances wrapped in effects :) |
|
Looks good :) There's a lot of tests to add, though. Maybe I'll just add them and then we'll have sth like TDD ;) One thing that we'll need to decide is how to re-use instances. Right now we are re-using anything that is created by a resource - and this makes sense. When creating an instance of a class, do we want to re-use it? That is, should the following (assuming not only case class A
case class B(a1: A, a2: A)
val b = wireX[B]generate either (1): val b = B(A(), A())or (2): val b = {
val x = A()
B(x, x)
}Here it doesn't make a difference, but maybe for some cases it does make a difference whether a dependency is a singleton and re-used, or not. Probably (1) is the better default, as it follows other DI frameworks where "dependent" scope is the default. And we could achieve singleton by explicitly passing in the instance. So I guess that's solved, or do you have another opinion? :) |
6b43819 to
ee50b16
Compare
ee50b16 to
42b5eea
Compare
| .dependsOn(macrosAkka, testUtil) | ||
| .jvmPlatform(scalaVersions = scala2) | ||
|
|
||
| lazy val macrosCatsEffect = projectMatrix |
There was a problem hiding this comment.
I think I'd rename this to macrosAutoCats, and similarly, the package to .auto.cats. The current package name is way too long ;)
There was a problem hiding this comment.
how about .auto.catssupport? .auto.cats clashes with the cats package
There was a problem hiding this comment.
hm it conflicts, how? I guess import macwire.auto.cats._ or import macwire.auto.cats.autowire should work just fine? I've got a tapir.integ.cats package and as far as I know it works just fine ;)
We can come up with a different name, though ... however catssupport looks cumbersome. Maybe .autocats? ;)
| !name.startsWith("java.lang.") && !name.startsWith("scala.") | ||
| } | ||
|
|
||
| def findeProvider(tpe: Type): Option[Tree] = findInstance(tpe) |
| In case you need to build an instance from some particular instances and factory methods it's recommended to use `autowire`. This feature is intended to interpolate with fp libraries (currently we support `cats`). | ||
|
|
||
| `autowire` takes as an argument a list which may contain: | ||
| * instances (e.g. `new A()`) |
There was a problem hiding this comment.
I think values would be more correct. Any value will do.
There was a problem hiding this comment.
In fact ... do we have tests, that you can use a sub-type, where the dependency is of a super-type? E.g. I declare that I need a dependency of type trait A, but I provide a value of type class AA extends A. Same for resources etc.
There was a problem hiding this comment.
For now we don't have tests for this case and we do not currently support it. I will add it to todo list
There was a problem hiding this comment.
Maybe let's keep the todo as issues :) I've created #183 for this
| * factory methods (e.g. `C.create _`) | ||
| * cats.effect.Resource (e.g. `cats.effect.Resource[IO].pure(new A())`) | ||
| * cats.effect.IO (e.g. `cats.effect.IO.pure(new A())`) | ||
| Based on the given list it creates a set of available instances and performs `wireRec` bypassing the instances search phase. The result of the wiring is always wrapped in `cats.effect.Resource`. For example: |
There was a problem hiding this comment.
what if multiple values for a given type are found? E.g. through a value and a resource? I think it should be an error
There was a problem hiding this comment.
Currently it searches for instances, then resources, then effects. I agree that is should fail in such case, also it may be worth to check if all passed instances/resources/factory methods are used in the generated code.
|
|
||
| val theDatabaseAccess: Resource[IO, DatabaseAccess] = Resource.pure(new DatabaseAccess()) | ||
|
|
||
| val theUserStatusReader: Resource[IO, UserStatusReader] = autowire[UserStatusReader](theDatabaseAccess) |
|
Actually I'm still not sure if we want to support no parameters constructors. import cats.effect._
import cats.effect.unsafe.implicits.global
class MutableConfig() {
var port: Option[Int] = None
var host: Option[String] = None
}
class Service(cfg: MutableConfig) {
println(s"[${cfg.host}]:[${cfg.port}]")
}
object Main extends App {
def loadConfig(): Resource[IO, MutableConfig] = Resource.pure {
val mc = new MutableConfig()
mc.host = Some("xyz")
mc.port = Some(8080)
mc
}
val cfg = loadConfig()
val service = autowire[Service]()
service.allocated.unsafeRunSync()._1
}it works and prints |
2bc32fb to
53cdea2
Compare
No description provided.