Play Framework PathBindable with Dependency Injection - scala

I'm migrating a Scala Play application to 2.5 and am currently moving my components to dependency injection. There's one place left where I'm at a loss how to do it though. I have a PathBindable implicit conversion defined in the companion object:
object Task {
implicit def pathBindable(implicit stringBinder: PathBindable[String]) =
new PathBindable[Task] {
...
}
}
The implementation of the PathBindable needs to look up the object from a repository, but I haven't found a way to dependency-inject the repository here. As a workaround I'm using the now deprecated Play object:
val tasks = Play.application(Play.current).injector.instanceOf[TasksRepository]
Any ideas how to solve this properly?

According to Lightbend Engineer Greg Methvin, PathBindables should only depend on the state in the path. The reason is that the code runs on the IO thread and should therefore be fast and not block.

I think this is the only way you can access stuff like this in objects.
A better idea is to create a the transformer like this:
class TaskPathBinder #Inject() ( tasks : TaskRepository ) extends PathBindable[Task]{
// implementiation
}
and than inject it in services like this
class NeedsTaskPathBinder #Inject() ( service : SomeSerive ) (implicit taskPathBinder : TaskPathBinder) {
...
}
Hope the you get the idea.

Related

How do I create thread pools in Play 2.5.x?

I am currently on Play 2.4.2 and have successfully created thread pools using the following below:
package threads
import scala.concurrent.ExecutionContext
import play.api.libs.concurrent.Akka
import play.api.Play.current
object Contexts {
implicit val db: ExecutionContext = Akka.system.dispatchers.lookup("contexts.db-context")
implicit val pdf: ExecutionContext = Akka.system.dispatchers.lookup("contexts.pdf-context")
implicit val email: ExecutionContext = Akka.system.dispatchers.lookup("contexts.email-context")
}
and then in the code with...
Future{....}(threads.Contexts.db)
We are ready to upgrade to Play 2.5 and having trouble understanding the documentation. The documentation for 2.4.2 uses Akka.system.dispatchers.lookup, which we use without issue. The documentation for 2.5.x uses app.actorSystem.dispatchers.lookup. As far as I know, I have to inject the app into a Class, not an Object. Yet the documentation clearly uses an Object for the example!
Has anyone successfully created thread pools in Play 2.5.x that can help out? Is it as simple as changing Contexts to a class, then injecting it wherever I would like to use this threading? Seems odd since to use the default ExecutionContext I just have to make an implicit import.
Also, we are using Play scala.
If you simply change your Contexts to a class, then you will have to deal with how to get an instance of that class.
In my opinion, if you have a number of thread pools that you want to make use of, named bindings are the way to go. In the below example, I will show you how you could accomplish this with guice.
Note that guice injects depedencies at runtime, but it is also possible to inject dependencies at compile time.
I'm going to show it with the db context as an example. First, this is how you will be using it:
class MyService #Inject() (#Named("db") dbCtx: ExecutionContext) {
// make db access here
}
And here's how you could define the binding:
bind[ExecutionContext].qualifiedWith("db").toProvider[DbExecutionContextProvider]
And somewhere define the provider:
class DbExecutionContextProvider #Inject() (actorSystem: ActorSystem) extends Provider[ExecutionContext] {
override def get(): ExecutionContext = actorSystem.dispatchers.lookup("contexts.db-context")
}
You will have to do this for each of your contexts. I understand this may be a little cumbersome and there may actually be more elegant ways to define the bindings in guice.
Note that I have not tried this out. One issue you might stumble upon could be that you'll end up with conflicts, because play already defines a binding for the ExecutionContext in their BuiltinModule. You may need to override the binding to work around that.

How to get application.conf variable in an object using Scala and Play 2.5.x?

I used to get the application.conf variable in Play 2.4.x with Play.current.configuration.getString('NAME_HERE'), and it was working good in class, object and companion object too.
Now, I'm using Play 2.5.4 with Scala in a new project, and I won't use this Play.current, because it's deprecated, but there is an alternative using DI, like this :
class HomeController #Inject() (configuration: play.api.Configuration) extends Controller {
def config = Action {
Ok(configuration.underlying.getString("db.driver"))
}
}
This DI Injection works like a charm in class, but in this project, I need to get the variable db.driver in a object? And as far I know, with an object I can't use DI.
Maybe using Guice would help?
You can use #Singleton annotated class instead of object
trait Foo {}
#Singleton
class FooImpl #Inject()(configuration: play.api.Configuration)) extends Foo {
//do whatever you want
}
#Singleton makes the class singleton.It feels bit awkward because Scala itself natively have syntax object to create a singleton, But this is the easiest and probably best solution to DI into a singleton.
You also may create the singleton eagerly like the code below.
bind(classOf[Foo]).to(classOf[FooImpl])asEagerSingleton()
for more detail Info, You can look up Google Guice Wiki and Playframework site
EDIT
How you call it is exactly the same as how you DI in Playframework2.5.
class BarController #Inject()(foo: Foo) extends Controller {
//Do whatever you want with Foo
}
Guice basically generates new instance every time you DI, Once you put #Singleton, Guice use only one instance instead.
DI is for anti-high coupling.So when you want to use a class you defined from another class,You need to DI otherwise the classes are highly coupled which end up making it harder to code your unit test.
FYI, You can use them outside of Play with this technique.
Create an Instance of class which does DI via Playframework Guice Independently in Scala
Have you tried
import com.typesafe.config.ConfigFactory
val myConfig = ConfigFactory.load().getString("myConfig.key")
Above approach doesn't require you to convert your object to singleton class.
You can do
Play.current.configuration
however that will (probably) no longer be possible with Play 2.6.
Ideally, however, you would pass the configuration in as a parameter to that method of the object or, use a class instead of an object.
What I somtimes do to migrate 'from object to class':
class MyComponent #Inject() (config: Configuration) {
// here goes everything nice
def doStuff = ???
}
object MyComponent {
#deprecated("Inject MyComponent")
def doStuff = {
val instance = Play.current.injector.instanceOf[MyComponent]
instance.doStuff
}
}
This way, you're not breaking existing code while all users of your methods can slowly migrate to using classes.

Alternative to using Akka.system inside an object

I am learning the Play Framework together with Scala, and I looked at the reactive-stocks tutorial that comes with activator for learning more about the framework.
In the learning project that I am creating (a simple chat) I want to have something similar to this snippet taken out from the tutorial:
object StocksActor {
lazy val stocksActor: ActorRef = Akka.system.actorOf(Props(classOf[StocksActor]))
}
That is, an actor that will only be instanciated one time on the application. But I found out that Akka.system is deprecated, so I should use dependency injection to get the ActorSystem. How would I do dependency injection in an Object?
object ChatRoomsActor #Inject() (actorSystem: ActorSystem) {
lazy val ref: ActorRef = actorSystem.actorOf(Props(classOf[ChatRoomsActor]))
}
I tried this code, but it doesn't work.

Unit Testing AKKA actors

I am doing a web application with Scala and Akka actors and I'm having some troubles with the tests.
In my case I need to taste an actor who talks with the Database. To do the unit testing I would like to use a Fake Database but I can't replace the new with my desired fake object.
Let's see some code:
Class MyActor extends Actor {
val database = new Database()
def receive = { ... }
}
And in the tests I would like to inject a FakeDatabase object instead Database. I've been looking in Internet but the best that I found is:
Add a parameter to the constructor.
Convert the val database to a var so in the test I could access the attribute by the underlying and replace it.
Both solutions solve the problem but are very dirty.
Isn't a better way to solve the problem?
Thanks!
The two primary options for this scenario are:
Dependency Injection Use a DI framework to inject a real or mock service as needed. In Akka: http://letitcrash.com/post/55958814293/akka-dependency-injection
Cake Pattern This is a Scala-specific way of achieving something akin to dependency injection without actually relying on injection. See: Akka and cake pattern
Echoing the advice here, I wouldn't call injecting the database in the constructor dirty. It might have plenty of benefits, including decoupling actor behaviour from the particular database instance.
However if you know there is only ONE database you will be always using in your production code, then think about defining a package level accessible constructor and a companion object returning a Props object without parameters by default.
Example below:
object MyActor {
def props() : Props = Props(new MyActor(new Database()))
}
class MyActor private[package](database : IDatabase) extends Actor {
def receive = { ... }
}
In this case you will still be able to inject the test database in your tests case (given the same package structure), but prevent users of your code from instantiating MyActor with unexpected database instance.

Dependency injection with Scala

I was searching a way of doing dependency injection in Scala kind of like Spring or Unity in C# and I found nothing really interesting.
MacWire: I don't understand the benefit as we have to give the class in wire[CASS]. So what's the point if you give the implementation when you call wire? I can do new CASS it will be the same.
Cake pattern with self type: Seems to not answer what I'm searching for.
So I decided to make my implementation and ask you what do you think because it's surprising me that nothing like this has been done before. Maybe my implementation have lot's of issues in real life also.
So here is an example:
trait Messenger {
def send
}
class SkypeMessenger extends Messenger {
def send = println("Skype")
}
class ViberMessenger extends Messenger {
def send = println("Viber")
}
I want here to inject everywhere in my app the implementation configured in only one place:
object App {
val messenger = Inject[Messenger]
def main(args: Array[String]) {
messenger.send
}
}
Note the Inject[Messenger] that I define like below with the config I want (prod or dev):
object Inject extends Injector with DevConfig
trait ProdConfig {
this: Injector =>
register[Messager](new SkypeMessager)
register[Messager](new ViberMessager, "viber")
}
trait DevConfig {
this: Injector =>
register[Messager](new ViberMessager)
register[Messager](new ViberMessager, "viber")
}
And finally here is the Injector which contains all methods apply and register:
class Injector {
var map = Map[String, Any]()
def apply[T: ClassTag] =
map(classTag[T].toString).asInstanceOf[T]
def apply[T: ClassTag](id: String) =
map(classTag[T].toString + id).asInstanceOf[T]
def register[T: ClassTag](instance: T, id: String = "") = {
map += (classTag[T].toString + id -> instance)
instance
}
}
To summaries:
I have a class Injector which is a Map between interfaces/traits (eventually also an id) and an instance of the implementation.
We define a trait for each config (dev, prod...) which contains the registers. It also have a self reference to Injector.
And we create an instance of the Injector with the Config we want
The usage is to call the apply method giving the Interface type (eventually also an id) and it will return the implementation's instance.
What do you think?
You code looks a lot like dependency injection in Lift web framework. You can consult Lift source code to see how it's implemented or just use the framework. You don't have to run a Lift app to use its libraries. Here is a small intro doc. Basically you should be looking at this code in Lift:
package net.liftweb.http
/**
* A base trait for a Factory. A Factory is both an Injector and
* a collection of FactorMaker instances. The FactoryMaker instances auto-register
* with the Injector. This provides both concrete Maker/Vender functionality as
* well as Injector functionality.
*/
trait Factory extends SimpleInjector
You can also check this related question: Scala - write unit tests for objects/singletons that extends a trait/class with DB connection where I show how Lift injector is used.
Thanks guys,
So I make my answer but the one from Aleksey was very good.
I understand better the Cake Pattern with this sample:
https://github.com/freekh/play-slick/tree/master/samples/play-slick-cake-sample
Take a look also to the other implementations without DI and compare:
https://github.com/freekh/play-slick/tree/master/samples/
And so the cake pattern doesn't have a centralized config like we can have with my shown lift style DI. I will anyway use the Cake pattern as it fits well with Slick.
What I didn't like with Subcut is the implicits everywhere. I know there is a way to avoid them but it looks like a fix to me.
Thanks
To comment on MacWire, you are right that you could just use new - and that's the whole point :). MacWire is there only to let you remove some boilerplate from your code, by not having to enumerate all the dependencies again (which is already done in the constructor).
The main idea is that you do the wiring at "the end of the world", where you assemble your application (or you could divide that into trait-modules, but that's optional). Otherwise you just use constructors to express dependencies. No magic, no frameworks.