score:3
I saw this awesome post last week: http://www.schibsted.pl/2016/04/dependency-injection-play-framework-scala/
score:10
Ok. I will assume you have two classes. First we will have your Client
class:
@Singleton // this is not necessary, I put it here so you know this is possible
class Client @Inject() (ws:WSClient, baseUrl: String) {
// Since this controller is not annotated with @Inject
// it WILL NOT be used when binding components
def this(ws:WSClient) = this(ws, "<url string>")
def getResponse() = {
// do something using ws object
}
}
Then you have another class that uses Client
, per instance, a controller:
class MyController @Inject() (client: Client) extends Controller {
def someAction = Action {
// do something with client object
}
}
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:
import play.api.Configuration
class Client @Inject() (ws:WSClient, configuration: Configuration) {
def getResponse() = {
val baseUrl = configuration.getString("key.to.baseUrl")
// do something using ws object and baseUrl
}
}
But, if you really want your Client
object to receives a String
, then we need to tell Play which String needs to be injected:
package com.acme.modules
import com.google.inject.AbstractModule
import com.google.inject.name.Names
class MyModule extends AbstractModule {
def configure() = {
bind(classOf[String])
.annotatedWith(Names.named("baseUrl")) // attention to the name here. It will be used below
.toInstance("http://api.example.com/")
}
}
And then enable this module by adding the following line to your application.conf
:
play.modules.enabled += "com.acme.modules.MyModule"
After that, we will change Client
to be specific about which String
it is expecting:
import play.api.Configuration
// @Named needs to receive the same value defined at the module class.
class Client @Inject() (ws:WSClient, @Named("baseUrl") baseUrl: String) {
def getResponse() = {
val baseUrl = configuration.getString("key.to.baseUrl")
// do something using ws object and baseUrl
}
}
Update after question edit:
Give the structure you want/need:
Controller Action --> Determine Plugins to Execute --> Execute Plugins ---> Plugin1
Your code can also follow that path with classes like this:
MyController -> PluginResolver -> Plugin
-> PluginRunner ->
And, then, you can have:
Controller:
class MyController @Inject() (
pluginResolver: PluginResolver,
pluginRunner: PluginRunner
) extends Controller {
def action = Action {
val plugins = pluginsResolver.resolve(/* give a criteria to select plugins */)
val someResultFromPluginsExecution = pluginsRunner.run(plugins)
// map result from plugins execution to a play play.api.mvc.Result
// return the play.api.mvc.Result
}
}
Plugin classes:
import play.api.inject.Injector
class PluginResolver @Inject()(injector: Injector) {
def resolve(/* some criteria to resolve plugins */): Seq[Plugin] = {
val pluginsClasses = ... // find the necessary plugins based on the criteria
pluginsClasses.map { pluginClass => injector.instanceOf(pluginClass) }
}
}
// ExecutionContext is not really necessary, but maybe you want/need
// another thread pool to execute plugins
class PluginRunner @Inject()(implicit executionContext: ExecutionContext) {
def run(plugins: Seq[Plugin]): Seq[PluginExecutionResult] = {
// run the plugins
// return the result
}
}
trait Plugin {
def execute(): PluginExecutionResult
}
The real magic here happens at the PluginResolver
. It uses a play.api.inject.Injector
to create plugins instances and then your plugins can use Dependency Injection. Per instance:
class PluginThatNeedsWSClient @Inject(wsClient: WSClient) extends Plugin {
def execute(): PluginExecutionResult = {
// Use wsClient to call a remote service
// return the execution result
}
}
Reference:
Source: stackoverflow.com
Related Query
- Play Scala Dependency injection: How to use it
- How to fix dependency injection when upgrading play framework from 2.5.x to 2.6.x Scala
- How to use IntelliJ with Play Framework and Scala
- How do you use play framework as a library, in a scala project
- How to use play-plugins-mailer with Play 2.3 and Scala 2.11?
- How can I use OrientDB from a Scala / Play 2.2 project?
- How to import Play framework as a dependency in Scala project
- How to properly use Scala Play Anorm and Option[String] to insert NULL SQL
- How do you use DTOs in Play Framework scala templates?
- Scala Play Guice Dependency Injection Fails
- How to use Java libraries asynchronously in a Scala Play 2.0 application?
- How to use WebSockets in Scala using Play Framework?
- How to use configuration in scala play 2.5.8 in an object
- Dependency Injection in Tests in Play Scala App s
- How to use provider for dependency injection using guice in playframework
- How do make a `CustomExecutionContext` available for dependency injection in a Play 2.6 controller?
- Scala Play 2 Guice dependency injection with traits
- How to use secret key in Play Scala application
- Play 2.5 scala import class with Dependency Injection
- scala play 2.5 and dependency injection into actor
- How do I use an unmanaged dependency in this simple Play example?
- How to use Memcached with the Scala Play Framework 2.2?
- Scala Dependency Injection in Play Framework
- Scala Play test can't find WSClient during dependency injection
- Dependency Injection (DI) in Scala with Play
- How to use POST method in scala form in play framework?
- Scala - Play - How to mock import play.api.libs.concurrent.CustomExecutionContext in Test and use it as an implicit param?
- How do you use play scala specs2 matchers across multiple files
- How to add a scala dependency to a Java project in intelliJ that use maven
- How to use fcm(firebase cloud messaging) with scala play framework to send notification?
More Query from same tag
- Int value of Prod in shapeless
- Play! JSON conversion of scala Slick one-to-many relations
- is JSON4S compatible with spark 2.4.0 and EMR 5.26.0
- How to use isLetter on scala arguments from main method?
- Creating a Json array in Scala
- Creating JSON file with for loop in scala
- SQLTransientConnectionException after upgrading MariaDB connector
- Is it possible to show the values for all keys in sbt?
- Play framework: play.api.mvc.DefaultJWTCookieDataCodec decode: could not decode JWT: null
- Scalatra Logging Error
- What is the combination of flatMap and filter?
- Scala: type arguments do not conform to class type parameter bounds
- Function literal with multiple implicit arguments
- How to test Zentasks sample app from Play 2.0
- scala implicit gets imported only on use
- Difference between Tuple and List[Any] in Scala?
- Scala web application security
- mininum value of struct type column in a dataframe
- Scala Spark - udf Column is not supported
- RDD data into multiple rows in spark-scala
- How to avoid an extra trailing newline when using Scala's sys.process to shell out
- Salat - how to lookup remapped values from a context
- Scodec: Using vectorOfN with a vlong field
- SPARK RDD Between logic using scala
- Building Spark using Maven fails
- How to get ROUTE_PATTERN from request in play 2.6 scala
- Combining the elements of 2 lists
- Why is object creation fast in Scala?
- Scala's compiler lexer
- Code runs for sometime and then throws Communications link failure Exception MySQL