Created by Oleg Ilyenko @easyangel
inject [SomeClass]
... or this one ...
inject [Database] (identified by 'remote and by default new Riak)
class OfficialMessageService(implicit inj: Injector)
extends MessageService with Injectable {
val officialGreeting =
inject [String] (identified by "greeting.official")
def getGreetMessage(name: String) =
s"$officialGreeting, $name!"
}
and Module of course
class UserModule extends Module {
bind [MessageService] to new OfficialMessageService
binding identifiedBy "greeting.official" to "Welcome"
}
bind [ActorSystem] to new ActorSystem
Non-lazy binding
bind [Server] toNonLazy new HttpServer
Provider binding
bind [Connection] toProvider inject[Database].getConnection
def tokenModule = new Module {
bind [Tokens] to new TokenRepo(db = inject [Database])
}
def dbModule = new Module {
bind [Database] to new Riak
}
def appModule = tokenModule :: dbModule
and then test it
def mocksModule = new Module {
bind [Database] to new InMemoryDb
}
implicit val testModule = mocksModule :: appModule
trait Injector {
def getBinding(identifiers: List[Identifier]): Option[Binding]
def getBindings(identifiers: List[Identifier]): List[Binding]
// ...
}
class TokenRepo(db: Database, metrics: Metrics) extends Tokens {
// ...
}
injected macro
bind [Tokens] to injected [TokenRepo]
compiled to
bind [Tokens] to new TokenRepo(
db = inject [Database],
metrics = inject [Metrics])
bind [Tokens] to injected [TokenRepo] (
'db -> inject [Database] ('tokensOnly))
compiled to
bind [Tokens] to new TokenRepo(
db = inject [Database] ('tokensOnly),
metrics = inject [Metrics])
binding identifiedBy "intAdder" to
((a: Int, b: Int) => a + b)
binding identifiedBy "mapping" to Map(
"scala" -> "http://scala-lang.org",
"play" -> "http://www.playframework.com",
"akka" -> "http://akka.io"
)
inject
val intAdder = inject [(Int, Int) => Int]
val mapping = inject [Map[String, String]]
class UserModule extends Module {
bind [MessageService] when (inDevMode or inTestMode) to
new SimpleMessageService
bind [MessageService] when inProdMode to
new OfficialMessageService
}
def inDevMode(implicit inj: Injector) = {
val mode = inject [Mode]
Condition(mode == Dev)
}
class MyModule extends Module {
bind [ActorSystem] to
ActorSystem("ScaldiExample") destroyWith (_.shutdown())
bind [Database] to new Mongo initWith (_.start())
}
implicit val injector = new MyModule
// do stuff ...
injector.destroy()
class Application(implicit inj: Injector)
extends Controller with Injectable {
val messageService = inject [MessageService]
def index = Action {
Ok(views.html.index(
messageService.getGreetMessage("Test User")))
}
}
class MyModule extends Module {
binding to new Application
bind [MessageService] to new OfficialMessageService
}
object Global extends GlobalSettings with ScaldiSupport {
def applicationModule =
new MyModule :: new SomeOtherModule
}
GET / @controllers.Application.index
inject [Application]
inject [Mode]
inject [Configuration]
def applicationModule =
new MyModule ::
new ControllerInjector
bind [Thing] when (inDevMode or inTestMode or inProdMode) to
new SomeThing
All configuration properties are also available as bindings
inject [String] (identified by "db.host")
inject [Int] (identified by "db.port")
class Receptionist(implicit inj: Injector)
extends Actor with AkkaInjectable {
val orderProcessorProps = injectActorProps [OrderProcessor]
val priceCalculator = injectActorRef [PriceCalculator]
def receive = {
case PlaceOrder(userName, itemId, netAmount) =>
val processor = context.actorOf(orderProcessorProps)
// ...
}
}
class OrderModule extends Module {
bind [ActorSystem] to ActorSystem("ScaldiExample")
destroyWith (_.shutdown())
binding toProvider new Receptionist
binding toProvider new OrderProcessor
binding toProvider new PriceCalculator
}