Skip to content

Commit

Permalink
Construct root instances with factory methods (#192)
Browse files Browse the repository at this point in the history
* Construct root instance with given factory methods

* Add todo for partial applied functions
  • Loading branch information
mbore authored Jan 5, 2022
1 parent 93e4fc8 commit 5d6a9cf
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class CatsProvidersGraphContext[C <: blackbox.Context](val c: C, val log: Logger
/** We assume that we cannot use input provider directly, so we create a result object with available constructors.
* It's a mimic of `wire`'s property
*/
val (resolvedCtx, rootProvider) = maybeResolveParamWithCreator(resolvedFMContext)(rootType)
val (resolvedCtx, rootProvider) = (maybeResolveWithFactoryMethod(resolvedFMContext)(rootType) orElse maybeResolveParamWithCreator(resolvedFMContext)(rootType))
.getOrElse(c.abort(c.enclosingPosition, s"Cannot construct an instance of type: [$rootType]"))

val inputProvidersTypes = inputProviders
Expand Down Expand Up @@ -119,6 +119,11 @@ class CatsProvidersGraphContext[C <: blackbox.Context](val c: C, val log: Logger
inputProviders ++ resultContext.providers.diff(inputProviders)
}

private def maybeResolveWithFactoryMethod(ctx: BuilderContext)(param: c.Type): Option[(BuilderContext, Provider)] = ctx.providers.find {
case fm: FactoryMethod => fm.resultType <:< param
case _ => false
}.map(r => (ctx, r))

private def maybeResolveParamWithCreator(ctx: BuilderContext)(param: c.Type): Option[(BuilderContext, FactoryMethod)] =
log.withBlock(s"Resolving creator for [$param]") {
def maybeResolveParams(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class A()
class B(val a: A)

val created = scala.collection.mutable.ListBuffer[String]()

def makeB(a: A) = {created.append("b"); new B(a)}

object Test {
val theB = autowire[B](makeB _)

}

val theB: B = {
import cats.effect.unsafe.implicits.global
Test.theB.allocated.unsafeRunSync()._1
}

require(theB.a != null)
require(created.size == 1)
require(created(0) == "b")
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class A()
class B(val a: A)

val created = scala.collection.mutable.ListBuffer[String]()

def makeB(s: String, a: A) = { created.append("b"); created.append(s); new B(a)}

object Test {
val theB = autowire[B](makeB("s", _))

}

val theB: B = {
import cats.effect.unsafe.implicits.global
Test.theB.allocated.unsafeRunSync()._1
}

require(theB.a != null)
require(created.size == 2)
require(created(0) == "b")
require(created(0) == "s")

0 comments on commit 5d6a9cf

Please sign in to comment.