EzDevInfo.com

scaldi

Lightweight Scala Dependency Injection Library Scaldi - Lightweight Scala Dependency Injection Library scaldi - lightweight dependency injection library

Managed controllers in Play 2.3 with DI (Scaladi / Guice)

thank you in advance for taking the time to take a look at my current problem with play.

I am still trying out the Playframework, currently in version 2.3.

At the moment I try to figure dependency injection out. I followed the tutorials provided in the activator for guice as well as scaladi and always resulting in the same compiler error:

play.PlayExceptions$CompilationException: Compilation error[object Application is not a member of package controllers Note: class Application exists, but it has no companion object.]

This makes me think I am missing a more universal part of the Playframework because the problem is not tied to a specific DI framework.

So let me describe what I tried with scaladi (any working solution with guice would also be appreciated):

defining the route in conf/routes:

GET     /        @controllers.Application.index

(added the @ for support of managed controllers which is supported since play 2.1 afaik)

defining the controller:

    package controllers

    import scaldi.{Injector, Injectable}
    import scala._
    import play.api._
    import play.api.mvc._
    import services.GreetingService

          class Application(implicit inj: Injector) extends Controller with Injectable  {
            val greetService= inject [GreetingService]

            def index = Action {
              Ok("Here I am")
            }
         }

defining the Global for modifing the GlobalSetting under app\Global.scala:

import modules.ApplicationModule
import play.api.GlobalSettings
import scaldi.play.ScaldiSupport

object Global extends GlobalSettings with ScaldiSupport {

    def applicationModule = new ApplicationModule
}

and finally the application module under app\modules\ApplicationModule.scala:

package modules

    import controllers.Application
    import scaldi.Module

    class ApplicationModule extends Module {
      binding to new Application
    }

So I really would appreciate any help to figure out why Application class could not be located within the package controllers. Also again I would be happy about any working solution may it be guice or scaladi.

Thank you!

Edit: The problem was a second controller for a different route that was also registered under "/conf/routes/". This controller was not yet manged. So after I adapted the steps I described above to the second Controller everything worked fine.


Source: (StackOverflow)

message goes to dead letter instead of sender (akka router) [scala]

Actually I`m having trouble with getting my actor (router) system to work correctly. My Setup:

I`m trying to use an akka router within an play controller. For dependency injection I use scaldi.

scaldi module:

class UserDAOModule extends Module {
  binding to new ExampleRouter
  binding toProvider new UserDAOWorker
}

akka router:

class UserDAORouter(implicit inj:Injector) extends Actor with AkkaInjectable {

  val userDAOProps = injectActorProps[UserDAOWorker]

  var router = {
    val routees = Vector.fill(5) {
      val r = context.actorOf(userDAOProps)
      context watch r
      ActorRefRoutee(r)
    }
    Router(RoundRobinRoutingLogic(), routees)
  }

  override def receive: Receive = {
    case mm: MongoDBMessage =>
      router.route(mm, sender)
    case Terminated(a) =>
      router = router.removeRoutee(a)
      val r = context.actorOf(userDAOProps)
      context watch r
      router = router.addRoutee(r)
  }

}

worker:

class UserDAOWorker(implicit inj:Injector) extends Actor with Injectable {

  val db = inject[DefaultDB]
  val collection:JSONCollection = db("users")
  val currentSender = sender

  override def receive: Receive = {
    case InsertUser(user) => insertUser(user)
  }

  def insertUser(user:User) = {
    collection.save(user).onComplete {
      case Failure(e) => currentSender ! new UserDAOReturnMessage(Some(e), None)
      case Success(lastError) => currentSender ! new UserDAOReturnMessage(None, lastError)
    }
  }
}

When I send a message (insertUser message) to the router, it is routed correctly and the worker receives the message, but when the worker sends a message back to the sender it cant be delivered, so it is send to dead letter office. I cant figure out how to fix this. Is there someone able to help me?

Thanks in advance


Source: (StackOverflow)

Advertisements

Scala - how to cast Option[X] to Option[y]

I have simple service classes

trait ItemService[+A] {
  def getItem(id: Int): Option[A]
}
class MockItemService(implicit inj: Injector) extends ItemService[Item] with Injectable      {
  def getItem(id: Int) =  {
     Option(new Feature("My Headline",Author(2,"Barry White")))
  }
}

using scaldi im binding MockItemService to ItemService then accessing like

class Features(implicit inj: Injector) extends Controller with Injectable {
   val itemService = inject [ItemService[Item]]
   def item(cat:String, id:Int, urlTitle:String) = Action {   
      itemService.getItem(id).map { item => Ok(views.html.feature.item(item))      
   }.getOrElse(NotFound)    
  }  
}

what i want is for item to be of type Feature and not Item. Feature extends Item.


Source: (StackOverflow)

Scaldi dependency injection and Akka Actors

I'm currently exploring using Scaldi for Dependency Injection in a Play2.2 application.

I have read the documentation on Scaldi's website, but what is unclear to me is how to use it with Akka.

What I have so far in my project:

Models/ (Daos and case classes)
   User.scala
Services/  (Akka Actors)
   UserService.scala
   ProfileService.scala
Managers/  (Regular Manager Classes)
   UserManager.scala (The Trait Interface)
   UserManagerImpl.scala (An actual implementation)
   UserManagerMock.scala (Mocked version)
   etc..

In UserService.scala I would use an instance of the UserManager to do the work:

class UserService extends ServiceActor with Injection
{
    val userManager = inject[UserManager]

    def receive = {
        case Register(email: String, password: String)
    }
}

object UserService extends Service
{
    case class Register(email: String, password: String)

    override protected val actorRef = Akka.system.actorOf(Props[UserService].withRouter(SmallestMailboxRouter(resizer = Some(resizer))))
}

Then depending on the injected manager, the actor can be sort of mocked if it delegate all the work to the manager?

However, what if the managers needs to call other Services, which are just companion objects? Or Services calling other services that are also referenced via companion objects?

Does anyone have some pointers on how to integrate Akka with Scaldi?


Source: (StackOverflow)

DI Binding to a subclass

I'm wondering if it's possible to bind dependencies with following syntax:

bind [Environment[User, Authenticator]] to FakeEnvironment[User, SessionAuthenticator](testUser)

(this was taken from tests, actual binding in the Module is slightly more verbose)

where SessionAuthenticator has following signature:

case class SessionAuthenticator(val loginInfo : com.mohiva.play.silhouette.api.LoginInfo, ...)
    extends scala.AnyRef 
        with com.mohiva.play.silhouette.api.Authenticator 
        with scala.Product 
        with scala.Serializable {...}

and Authenticator:

 trait Authenticator extends scala.AnyRef {...}

But all I get is the following stacktrace during compilation:

[error] /home/mironor/projects/livrarium/test/controllers/CloudSpec.scala:22: overloaded method value to with alternatives:
[error]   [T <: com.mohiva.play.silhouette.api.Environment[services.User,com.mohiva.play.silhouette.api.Authenticator]](fn: => T)(implicit evidence$2: reflect.runtime.universe.TypeTag[T])scaldi.BoundHelper[T] <and>
[error]   (none: None.type)scaldi.BoundHelper[com.mohiva.play.silhouette.api.Environment[services.User,com.mohiva.play.silhouette.api.Authenticator]]
[error]  cannot be applied to (com.mohiva.play.silhouette.test.FakeEnvironment[services.User,com.mohiva.play.silhouette.impl.authenticators.SessionAuthenticator])
[error]       bind [Environment[User, Authenticator]] to FakeEnvironment[User, SessionAuthenticator](user)

This way I could choose which Authenticator to use only once in applicaiton's Module and inject it like this:

implicit val env = inject[Environment[User, Authenticator]]

instead of:

implicit val env = inject[Environment[User, SessionAuthenticator]]

What are my options?


Source: (StackOverflow)

why cant I bind to single actor instance (akka router) with scaldi?

I´m currently struggeling with implementing my Akka router logic using scaldi for dependency injection. Why cant I bind to a single actor instance with scaldi, since my actor is a router and I only want to have one single instance of it? The way I came to ask this question was another stackoverflow entry.

My scaldi Module:

class DAOModule extends Module {
  bind toProvider new UserDaoWorker
  binding to new UserDaoRouter
}

This way only one instance is created and as soon as I inject my router multiple times it gets a dead letter actor as sender from the sender() method.

When I change the binding to...

binding toProvider new UserDaoRouter

... it works perfectly fine, but every injection means a new instance of my router. Am I right?

So how can I achieve having only a single instance of my router which is injectable?

Thanks in advance


Source: (StackOverflow)

How do I register a binding with both delayed instantiation and as a singleton

I am new to scaldi. I have a class being used in my cloud environment configuration where I want two things to happen.

bind [EnvironmentInfo] to new EnvironmentInfo initWith(_.init())

First, I want it to be a singleton. It retrieves the runtime information (Google AppEngine in this case) and it should do this once on instantiation. It seems like initWith is a good choice.

Next, I want instantiation to be delayed until first request. Following the execution path it is being instantiated well before the first call.

If I can get delayed instantiation, then initWith should move to the class constructor.


Source: (StackOverflow)

Compilation error when using Scaldi

I am following the steps mentioned in Scaldi documentaiton. Following is my code.

class Game(players: List[Player], currentPlayer: Player,
           board: Board, active: Boolean, gamePersistor: GamePersistor) extends Injectable {

  def this(players: List[Player], currentPlayer: Player,
           board: Board, active: Boolean)(implicit inj: Injector) {
    this(players, currentPlayer, board, active, inject[GamePersistor])
  }
}

I get the following compilation error.

Error:(11, 49) not found: value inject
    this(players, currentPlayer, board, active, inject[GamePersistor])
                                                ^

Can someone help me solve this issue?


Source: (StackOverflow)

Is it possible to inject into an scala object with scaldi dependecy injection?

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


Source: (StackOverflow)

Injecting dependencies in tests in Play framework with scaldi

I'm looking for a way to inject a dependency into a Test (in /tests/models/) that looks like following:

class FolderSpec(implicit inj: Injector) extends Specification with Injectable{

  val folderDAO = inject [FolderDAO]

  val user = User(Option(1), LoginInfo("key", "value"), None, None)

  "Folder model" should {

    "be addable to the database" in new WithFakeApplication {
      folderDAO.createRootForUser(user)
      val rootFolder = folderDAO.findUserFolderTree(user)
      rootFolder must beSome[Folder].await
    }

  }
}

Where

abstract class WithFakeApplication extends WithApplication(FakeApplication(additionalConfiguration = inMemoryDatabase()))

/app/modules/WebModule:

class WebModule extends Module{
  bind[FolderDAO] to new FolderDAO
}

/app/Global:

object Global extends GlobalSettings with ScaldiSupport with SecuredSettings with Logger {
  def applicationModule = new WebModule :: new ControllerInjector
}

But at compilation time I have following stack trace:

[error] Could not create an instance of models.FolderSpec
[error]   caused by java.lang.Exception: Could not instantiate class models.FolderSpec: argument type mismatch
[error]   org.specs2.reflect.Classes$class.tryToCreateObjectEither(Classes.scala:93)
[error]   org.specs2.reflect.Classes$.tryToCreateObjectEither(Classes.scala:207)
[error]   org.specs2.specification.SpecificationStructure$$anonfun$createSpecificationEither$2.apply(BaseSpecification.scala:119)
[error]   org.specs2.specification.SpecificationStructure$$anonfun$createSpecificationEither$2.apply(BaseSpecification.scala:119)
[error]   scala.Option.getOrElse(Option.scala:120)

Sadly, I didn't find anything on the matter in Scaldi documentation.

Is there a way to inject things in tests?


Source: (StackOverflow)

Scaldi bindings to provider function (Map argument with injected key & value)

I'm trying to port this repo from Guice to Scaldi. I'm stack in this code from /app/utils/di/SilhouetteModule.scala (lines 60-65):

  Map(
    credentialsProvider.id -> credentialsProvider,
    facebookProvider.id -> facebookProvider,
    googleProvider.id -> googleProvider,
    twitterProvider.id -> twitterProvider
  ),

And here is where I'm now

class SilhouetteModule extends Module {

  bind[DelegableAuthInfoDAO[PasswordInfo]] to new PasswordInfoDAO
  bind[DelegableAuthInfoDAO[OAuth1Info]] to new OAuth1InfoDAO
  bind[DelegableAuthInfoDAO[OAuth2Info]] to new OAuth2InfoDAO
  bind[CacheLayer] to new PlayCacheLayer
  bind[HTTPLayer] to new PlayHTTPLayer
  bind[IDGenerator] to new SecureRandomIDGenerator
  bind[PasswordHasher] to new BCryptPasswordHasher
  bind[EventBus] to new EventBus


  bind[Environment[User, CachedCookieAuthenticator]] toProvider new Environment[User, CachedCookieAuthenticator](
    inject [UserService],
    inject [AuthenticatorService],
    // **this is where I don't know what to do**
    Map(
      credentialsProvider.id -> credentialsProvider,
      facebookProvider.id -> facebookProvider,
      googleProvider.id -> googleProvider,
      twitterProvider.id -> twitterProvider
    ),
    inject [EventBus]
  )
//... *Provider bindings below

What can I do to inject the Map like in the code above?

Can Scaldi bind to a function (like @Provides annotation in Guice) ?

thanks


Source: (StackOverflow)

Scaldi : Bind[T < AkkaInjectable] to TestProbe.ref

I'm trying to test an Actor A inside my Play 2.4 application with Scaldi. This actor is calling injectActorRef[B] that I want to mock with a TestKit.TestProbe.

Inside my specs2, I would like to be able to retrieve the probe for mocked B while providing the corresponding TestKit.TestProbe.ref to actor A.

I would like to do something like this :

implicit val inj = (new TestModule(){
    bind[TestProbe] identifiedBy 'probeForB to TestProbe()
    bind[B] to inject[TestProbe]('probeForB).ref
}).injector

inject[TestProbe]('probeForB).expectMsgType[] must ...

The issue is that the ref is an ActorRef and therefore does not match the expected Btype.

Is there a clean way to do that ? Can we specify an ActorRef to be returned by injectActorRef[B]?


I ended up overriding the bind for Actor A.

val probeForB = TestProbe()

implicit val inj = (new Module() {
    bind[A] to new A() {
       override def injectB(): ActorRef = probeForB.ref
    }
 }).injector

Source: (StackOverflow)

Depedency injection framework of Play and Scala?

I am from spring background, where we use Dependency Injections in our projects. Now i am on Play-Framework, where i am select Scala for development. With Scala i want to use dependency injection and i find out there are so many Dependency Injections frameworks are available for Scala. Spring also provide the support for Scala dependency injection framework. But i only need IOC container, so there is no need for using spring. In the Play-Framework documentation they use Google-Guice for Dependency injection framework. But i found out SCALDI also a nice Dependency Injection Framework for Scala.

I am still confusing which Dependency Injection frameworks good for Scala and Play-Framework. There are also compile time type safety framework are available. Please suggest me, go for which Dependency Injection Framework?


Source: (StackOverflow)

Scaldi - binding to single/multiple instances

I recently switched from SubCut to Scaldi and there's a feature I find undocumented/missing:

In SubCut, when you define a binding, you can choose between different binding modes - toSingle, toProvider, to moduleInstanceOf, toModuleSingle, which decide if the injected instances will be created once, or each time the bind is performed. I don't see the analogous behaviours explicitly defined in the Scaldi documentation, so I would like to make sure I understand how the different behaviours can be achieved in Scaldi:

By default the to method is lazy and creates the injected instance the first time it's "requested". There's a toNonLazy in the api which I guess creates the instance even before the first time it's "requested". And there's a toProvider, which in the following example...

bind [Widget] toProvider new ParticularWidget()

...would create a new ParticularWidget every time it is injected in an Injectable.

Am I understanding this correctly?


Source: (StackOverflow)