I am trying to use Play 2.5 dependency injection. I have following class which makes a call to REST api and parses the response
class Client @Inject()(ws:WSClient, baseUrl: string) {
def this(ws:WSClient) = this(ws, "<url string>")
def getResponse() = {....}
....
}
The caller of the code looks like below
var client = new Client(WS.client)
client.getResponse()
I am getting following warning.
object WS in package ws is deprecated: Inject WSClient into your component
I understand that i need to inject WS.Client instead of passing it explicitly to the Client constructor. But how do i do that?
=== Update ===
I don't want to inject Client or WSClient from the Controller. My controller creates objects and classes at run time and i want those objects to create Client Object. When i explicitly pass WS.client object to the Client object i get the above stated warning.
=== Update 2 ===
I have a plugin architecture in my application. When a a controller starts an action. It does not know what set of plugins it is going to execute. Some plugins would not need a WSClient and some of them would. So i dont want to couple the injection of WSClient into my controller. Each plugin independently decides if it wants to call a remote service. When a plugin decides to call the remote service, it should be able to inject WSClient in what ever client it wants to invoke.
Controller Action --> Determine Plugins to Execute --> Execute Plugins ---> Plugin1 (needs to call a remote api, create a client object, per say new Client(WS.Client)). This is where the injection should happen, not at the controller.
I saw this awesome post last week: http://www.schibsted.pl/2016/04/dependency-injection-play-framework-scala/
Ok. I will assume you have two classes. First we will have your
Client
class:Then you have another class that uses
Client
, per instance, a controller:The main point here is that the controller did not need to create a
Client
instance. It was automatically injected by Guice.Moreover, your client class needs a
baseUrl
and there is no place telling Play which value is needed there. If this is a configuration, than you can do something like this:But, if you really want your
Client
object to receives aString
, then we need to tell Play which String needs to be injected:And then enable this module by adding the following line to your
application.conf
:After that, we will change
Client
to be specific about whichString
it is expecting:Update after question edit:
Give the structure you want/need:
Your code can also follow that path with classes like this:
And, then, you can have:
Controller:
Plugin classes:
The real magic here happens at the
PluginResolver
. It uses aplay.api.inject.Injector
to create plugins instances and then your plugins can use Dependency Injection. Per instance:Reference:
play.api.inject.Injector