Trying to instantiate named(annotated) classes - scala

First of all, thanks for any effort to try and answer the question.
From the current application injector (play.api.Play.current.injector), how do I get a Named instance of a class?
I tried to cast the injector to a ScalaInjector (net.codingwell.scalaguice.InjectorExtensions.ScalaInjector) and to Guice Injector (com.google.inject.Injector), both unsuccessful.
The problem is that there are only 3 methods to instantiate a class, all of them are overloaded instanceOf[T]

For a normal dependency you would do
play.api.Play.current.injector.instanceOf[ProjectRepo]
When you want to retrieve a named dependency you can do
val qualifier = Some(QualifierInstance(Names.named("name")))
val bindingKey = BindingKey[ProjectRepo](Class[ProjectRepo], qualifier)
play.api.Play.current.injector.instanceOf[ProjectRepo](bindingKey)
Anyway you should only use the injector directly in very rare cases, makes sure there is not a simpler way to retrieve your dependencies.

When you need to inject a named dependency (in my case an ActorRef) you can also use a case class to help:
case class NamedActorHelper #Inject() (#Named("some-actor") actor: ActorRef)
class SomeActorSpec with GuiceOneAppPerSuite {
...
val someActor = app.injector.instanceOf[NamedActorHelper].actor
...
}
Replacing app with play.api.Play.current should also work.

Related

Use WSClient in scala app (play framework)

I'm not sure if there's something really basic that I'm missing, but I can't figure out how to use WSClient. I've seen all of the examples saying you need to pass the WSClient to a class as a dependency, which I've done, but when I run the program what do I actually pass to my class?
For example, my class signature is:
class myClassName(ws: WSClient)
But when I instantiate the class what do I actually pass to it? I'm also happy to ignore the Play! framework stuff if that makes it easier and just use SBT to run it (which I'm more familiar with).
It's unclear where you might be using a WSClient, but it is recommended that you let the Play framework 'manage' the instance of the client. When you instantiate your application, it gets injected:
class Application #Inject() (ws: WSClient) extends Controller {
...
}
What that means is that inside the ... you have access to ws as a value. You can instantiate myClassName using it:
class Application #Inject() (ws: WSClient) extends Controller {
val myclass = myClassName(ws) // passes the injected WSClient to myClassName
}
Or you can write a function that returns the WSClient, so some other area of your code can call into your Application object to get a object handler for it.
But the key is that the Application object gets that handle because of injection, which is the #Inject annotation.
If you need to generate a WSClient and manage it manually, there are good instructions here. The recommended implementation is reliant on Play! framework libraries, but doesn't depend on the Application.

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.

Play 2.5 + Slick + DI Issue

I have DAO defined as follows:
#Singleton
class MyDAO #Inject()(protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] {
I have an integration test which references this DAO:
class SomeIntegrationTest {
lazy val someVal = new MyDAO
}
How can I inject the DatabaseConfigProvider into the MyDAO in the SomeIntegrationTest? I cannot inject one in the constructor of the test because test classes do not take constructor parameters.
You can get your dependency injected by doing
val dbConfigProvider = app.injector.instanceOf[DatabaseConfigProvider]
where app is an instance of your FakeApplication. Without it, there is no way Play can inject your dependency for you. You can get an instance of FakeApplication by extending OneAppPerSuite, see the provided link for more details.
In general, there are three main ways you can gain access to some object(s) in your test:
manual creation of objects using the new keyword (not considered best practice)
injection via injector as shown here (either injecting objects directly or injecting a provider/factory which can get them for you)
in case of unit testing a class with some dependencies, having those dependencies mocked

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.