2

Is it possible to inject into an scala object with scaldi dependecy injection? If so, how can I get the injector?

I have an object SignUpForm which has to be a singleton...

object SignUpForm {

  val form = Form(
    mapping(
      "firstName" -> nonEmptyText,
      "lastName" -> nonEmptyText,
      "email" -> email.verifying(Constraints.userExists),
      "password" -> mapping (
        "main" -> nonEmptyText.verifying(Constraints.passwordLenth),
        "confirm" -> nonEmptyText
      )(Password.apply)(Password.unapply).verifying(Constraints.passwordConfirmation)
    )(Data.apply)(Data.unapply)

  )

  case class Password(
    main: String,
    confirm: String
  )

  case class Data(
    firstName: String,
    lastName: String,
    email: String,
    password: Password
  )
}

... and an object constraints

object Constraints {

  val userService = inject[UserService]

  def passwordConfirmation: Constraint[Password] = Constraint("password.confirm"){ password =>
    if (password.main.equals(password.confirm)) Valid else Invalid(Seq(ValidationError("password doesnt equal the confirmation password", "password.main", "confirm")))
  }

  def passwordLenth: Constraint[String] = Constraint("password.length"){ password =>
    if (password.length >= 8) Valid else Invalid(Seq(ValidationError("The minimum password length is " + 8 + " characters", "password.main", "length")))
  }

  def userExists: Constraint[String] = Constraint("user.exists"){ email =>
    if (userExistsWithEmail(email.toLowerCase)) Valid else Invalid(Seq(ValidationError("The user with email " + email + " already exists", "user", "email")))
  } ...

here is the problem -> userservice needs to be injected but it cant be injected as long as there is no implicit Injector passed as constructor argument (what is not possible because of the fact that we have an object here)

...
private def userExistsWithEmail(email: String):Boolean = {
    val result = Await.result(userService.retrieve(LoginInfo(CredentialsProvider.Credentials, email)),1 seconds)

     result match {
      case Some(u) => true
      case None => false
    }
  }
}

... how can I solve this problem?

Thanks in advance

heiningair
  • 441
  • 1
  • 6
  • 23
  • 1
    Unfortunately it is not possible with Scaldi or any other DI library (that I'm aware of). The whole point of dependency injection is to avoid usage of singleton objects. So I would strongly recommend you to avoid using them in most situations. – tenshi Oct 14 '14 at 18:48

1 Answers1

2

It looks like you've answered your own question. Objects are singletons that you don't get to initialize and therefor can't have constructor arguments.

Turn your Constraints object into a class and then you'll be able to inject the dependencies when you (or your DI framework) are creating it.

Gangstead
  • 4,152
  • 22
  • 35