subcut
Scala Uniquely Bound Classes Under Traits
I am looking at SubCut and Scaldi to use in my projects. The examples provided in their respective Getting Started documents seem very similar. Neither project seems to provide documentation beyond Getting Started and scala docs.
Could somebody summarize the practical differences between these frameworks primarily in terms of features and maturity/stability. I am looking into these packages because I need to be able to create and compose configuration dynamically at runtime. Runtime configuration is the main reason I am looking at these libraries instead of using implicits and/or the layer cake pattern to do DI/configuration, so run time configuration facilities are the most important to me. Also I do not think compiler plugins are an option for me, but both of these libraries can be used without their respective plugins with only a small increase in verbosity. I am on scala-2.9.2 for the moment.
I am also interested in suggestions for doing runtime DI/configuration directly in Scala, but converting my whole project to monadic style is also not an option for me.
Source: (StackOverflow)
Based on available documentation this task seems straightforward, however I've been hitting my head in the wall for a couple of days on this and still can't make it work for a simple inter-module dependency...
Here's a reduced example:
trait Bla {
def m: String
}
class BlaImpl(implicit val bindingModule: BindingModule) extends Bla with Injectable {
val s = inject[String]('bla)
def m = "got " + s
}
object Program extends App with Injectable {
implicit val bindingModule =
new NewBindingModule({ implicit module ⇒ module.bind[Bla] toSingle { new BlaImpl } }) ~
new NewBindingModule(_.bind[String] idBy 'bla toSingle "bla!")
val bla = inject[Bla]
assert(bla.m == "got bla!")
}
Running this code fails with the following error, When trying to build the BlaImpl instance:
org.scala_tools.subcut.inject.BindingException: No binding for key BindingKey(java.lang.String,Some(bla))
Debugging shows that the binding module handed to BlaImpl's constructor doesn't contain the 'bla String in its bindings, and that Program.bindingModule.bindings has all bindings (including the needed String).
I've seen other question similar but it dows refer only to composition but not to dependencies crossing module borders.
What am I doing wrong?
Source: (StackOverflow)
I have a Specs2RouteTest
"test a route with some modified dependencies" in {
bindingModule.modifyBindings { implicit module =>
module.bind[AuthorizationService].toModuleSingle { createMockAuthService("1") }
val req = createMockRequest("1")
val testApi = module.inject [ApiEndpoints](None)
Post(s"/api/v1/service", JsonEntity(req.toJson)) ~> testApi.routes ~> check {
....
}
}
}
I confirm that the modified binding is set within the test. But once it gets into the route I am back to seeing the bindings as set up in the test module. Generally this modifyBindings{} technique seems to work to keep tests isolated and when I'm doing unit testing I can swap out dependencies no problem... but on these integration tests I can't seem to make the route under test pick up any binding modifications. Am I doing something obviously wrong?
Source: (StackOverflow)
Would modifyBindings worked as promised this test should pass:
import org.scalatest.FunSuite
import org.scala_tools.subcut.inject.NewBindingModule
import org.scala_tools.subcut.inject.BindingModule
import org.scala_tools.subcut.inject.Injectable
import org.junit.Test
case class Resource1(name: String)
class ResourceClient(implicit val bindingModule: BindingModule) extends Injectable {
val res1 = inject[Resource1]
}
object Config1 extends NewBindingModule(module => {
module.bind[Resource1] toSingle new Resource1("name1")
})
class TestModifyBindings extends FunSuite {
@Test
def test1() {
implicit val bindingModule = Config1
val rc = new ResourceClient
assert(rc.res1.name == "name1")
Config1.modifyBindings { module =>
module.bind[Resource1] toSingle new Resource1("name2")
val rc2 = new ResourceClient //not sure if rc can be used here
assert(rc2.res1.name == "name2") //FAILS
}
}
}
Any ideas about what I missed?
Source: (StackOverflow)
I have a Play 2.1 application. I am also using Subcut for dependency injection, which is already set up and working for most parts of the application, except for one.
Say I have the following snippet of actor-related code:
import akka.actor._
import com.typesafe.plugin._
import play.api.Play.current
import play.api.libs.concurrent.Akka
class FoobarActor extends Actor {
def receive = {
// do stuff here
}
}
object Foobar {
val actor = Akka.system.actorOf(Props[FoobarActor])
}
Now, say I would like to inject some objects into each instance of the FoobarActor
using Subcut. This would require the actor class to extend Injectable
, with the BindingModule
passed into the constructor, like this:
import akka.actor._
import com.typesafe.plugin._
import play.api.Play.current
import play.api.libs.concurrent.Akka
import com.escalatesoft.subcut.inject.{Injectable, BindingModule}
class FoobarActor(implicit val bindingModule: BindingModule) extends Actor
with Injectable {
val bazProvider = inject[BazProvider]
val quuxProvider = inject[QuuxProvider]
def receive = {
// do stuff here
}
}
The question is: how is such an actor instantiated?
Typically, objects managed by Subcut are constructed in Subcut's configuration objects (i.e., objects that extend NewBindingModule
), or in the case of Play's controllers, in the Global
object (see play-subcut on github).
What would I replace Akka.system.actorOf(Props[FoobarActor])
with in order to override the instantiation of actors in order to pass in the binding module?
object Foobar {
val actor = /* what goes here? */
}
Source: (StackOverflow)
I am trying to integrate Subcut with my project for Dependency injection and am running into an issue integrating it with a third party library.
The library requires the location of a file to load which I am storing in my Play configuration and I want to inject the location using Subcut. Below is the module I have currently defined :
object ServerModule extends NewBindingModule (module => {
import module._
bind[String] idBy 'location toSingle {
Play.current.configuration.getString("file.location").getOrElse (
throw new IllegalStateException("Cannot find location")
)
}
bind[ThirdPartyLib] toSingle {
val location = inject [String] (Some('location.toString))
ThirdPartyLib fromFile location
}
bind[Controller] toProvider { implicit module => new Controller}})
This code compiles but at runtime it fails saying it cannot find the binding for the location String identified by 'location
.
Another thing I do not understand why I can do idBy 'location
but doing inject[T]('location)
causes compilation to fail? From looking at the code it appears that idBy
just converts a Symbol into a String then the inject
method only takes a String. Is this just a deficiency of the Subcut API or am I doing something wrong?
Source: (StackOverflow)
With SubCut I can define a BindingModule and use modifyBindings to get a new one which can overwrite some bindings and also add new bindings. Is there a utility where instead of saying
val module : BindingModule
val newModule = module.modifBindings(...)
I could instead do something like
val mergedModule = merge(module1,module2,module3,...)
The reason is I am writing an application with "pluggable" jars - each such jar will have a META-INF/bindings.properties file which will expose the class name of its BindingModule. My main entry jar will instantiate those BindingModules via reflection and then combine them.
The idea being that if the pluggable jars follow the convention of providing META-INF/bindings.properties then there is no new configuration needed to deploy the application.
Source: (StackOverflow)
I have a route defined as @com.xyx.abc(str: String) in my routes file.
I want to use this route in a template. I tried using
<a rel='nofollow' href="@com.xyx.abc("temp")/>
Obviously didn't work.
Thanks in advance.
Source: (StackOverflow)