Skip to content

Don't autowire no-arg constructors, or make this configurable? #184

Description

@adamw

Citing @mbore:

Actually I'm still not sure if we want to support no parameters constructors.
It may cause difficult to debug mistakes like "forgot to pass filled config", for example:

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 [None]:[None].
I see that it may reduce boilerplate in some cases, but I'm not sure if it's worth to risk.

Something to consider - I think no-arg implementations might be common, but the argument with configuration is also a valid one.

Maybe we could somehow make this configurable - either support no-arg constructors or not? Or better, maybe the configuration could include packages from which we want to autowire, or a blacklist of packages which should never be autowired?

However, it's challenging to provide such configuration at compile-time - I suppose it would need to be somehow available at the type level?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions