Last active
December 27, 2015 13:49
-
-
Save alexandru/7336282 to your computer and use it in GitHub Desktop.
Play / Subcut dependency injection in modules
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Helper for keeping track of the active project bindings | |
| // (because we don't want to hard-code those inside singleton objects) | |
| object Environment { | |
| def currentBindings = | |
| ref.get match { | |
| case null => | |
| throw new NullPointerException("No BindingModule currently registered (app not running?)") | |
| case value => | |
| value | |
| } | |
| def registerCurrentBindings(update: => BindingModule) { | |
| if (ref.get != null || !ref.compareAndSet(null, update)) | |
| throw new IllegalStateException("Cannot register new BindingModule (the current one must be deregistered)") | |
| } | |
| def unregisterBindings(current: BindingModule) { | |
| if (!ref.compareAndSet(current, null) && !ref.compareAndSet(null, null)) | |
| throw new IllegalStateException("Cannot unregister given BindingModule (not current)") | |
| } | |
| private[this] val ref = Atomic(null : BindingModule) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| trait HelloWorldController extends Controller { | |
| // abstract | |
| def usersDAL: UsersDAL | |
| def list = Action { req => | |
| val response = usersDAL.list(0, 100).map { list => OK(html.showUsers(list)) } | |
| Async(response) | |
| } | |
| // ... | |
| } | |
| object HelloWorldController extends HelloWorldController with Injectable { | |
| def bindingModule = Environment.current | |
| def usersDAL = inject [UsersDAL] | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class LifeCyclePlugin(app: play.Application) extends Plugin with Injectable { | |
| val bindingModule = new StandardBindings(app.getWrappedApplication) | |
| override def onStart() { | |
| Environment.registerCurrentBindings(bindingModule) | |
| } | |
| override def onStop() { | |
| Environment.unregisterBindings(bindingModule) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import com.escalatesoft.subcut.inject._ | |
| import play.api.libs.concurrent.Akka | |
| import play.api.{Play, Application} | |
| import akka.actor.ActorSystem | |
| import play.api.libs.concurrent.Execution.Implicits.defaultContext | |
| class StandardBindings(app: => Application) extends NewBindingModule(module => { | |
| import module._ | |
| lazy val config = Configuration.load() | |
| lazy val system = Akka.system(app) | |
| bind [Configuration] toSingle config | |
| bind [DBConnection] toSingle DBConnection(config.db, system)(app) | |
| bind [ActorSystem] toSingle system | |
| bind [Application] toSingle Play.current | |
| bind [GeoIP] toSingle GeoIP() | |
| // ... | |
| }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment