SlideShare a Scribd company logo
1 of 17
Download to read offline
DI in Play 2.4
Compile time
Dependency Injection
with macwire
Yann Simon
Dependency Injection
Runtime
VS
Compile Time
Runtime vs compile time DI
●
Runtime
✔
Support Lifecycle (start / stop)
●
Compile time
✔
Dependency graph checked by compiler
✔
No runtime overhead
source:
http://apmblog.compuware.com/2013/12/18/the-hidden-class-loading-performance-impact-of-the-spring-framework/
Compile time DI
●
With the cake pattern
– Talk “Structure your Play application with the cake
pattern (and test it)”
●
Slides: http://de.slideshare.net/yann_s/play-withcake-export2
●
Video: http://www.ustream.tv/recorded/42775808
●
With constructor parameters
DI with constructor parameters
class Dependency1
class Dependency2 {
def parse(input: String): Unit =
println(s"parse '$input' with '$this'")
}
class Service(dep1: Dependency1, dep2: Dependency2) {
def parse(input: String): Unit = dep2.parse(input)
}
val dep1 = new Dependency1
val dep2 = new Dependency2
val service = new Service(dep1, dep2)
Singleton or not
// singleton
val dep1 = new Dependency1
val dep2 = new Dependency2
val service = new Service(dep1, dep2)
// one instance per call
val dep1 = new Dependency1
def dep2 = new Dependency2
def service = new Service(dep1, dep2)
val or lazy val
val dep1 = new Dependency1
val service = new Service(dep1, dep2)
val dep2 = new Dependency2
java.lang.NullPointerException
lazy val dep1 = new Dependency1
lazy val service = new Service(dep1, dep2)
lazy val dep2 = new Dependency2
Complex dependency tree
lazy val dep1 = new Dependency1
lazy val dep2 = new Dependency2
lazy val dep3 = new Dependency3
lazy val dep4 = new Dependency4
lazy val dep5 = new Dependency5(dep3, dep4)
lazy val dep6 = new Dependency6(dep2, dep4)
lazy val dep7 = new Dependency7(dep5, dep6)
lazy val service = new Service(dep1, dep2, dep3, dep4, dep7)
With macwire
import com.softwaremill.macwire._
lazy val dep1 = wire[Dependency1]
lazy val dep2 = wire[Dependency2]
lazy val dep3 = wire[Dependency3]
lazy val dep4 = wire[Dependency4]
lazy val dep5 = wire[Dependency5]
lazy val dep6 = wire[Dependency6]
lazy val dep7 = wire[Dependency7]
lazy val service = wire[Service]
And that's all!
macwire
●
Macwire resolves dependencies based on the
type
– Compile error when ambiguous
– No good idea to have a String as dependency ;)
Macwire
●
https://github.com/adamw/macwire
●
Other features
– Accessing wired dynamically
– Interceptors
– Qualifiers
Integration of macwire with Play
●
Play 2.3
– Everything checked at compile time, expect...
routing... :(
●
Play 2.4
– Everything checked at compile time!
– https://github.com/yanns/TPA/pull/1/files
●
Demo
Macwire interceptor
●
Ex: monitor performance of ws calls:
– MonitoringInterceptor
lazy val videoGateway: VideoGateway = logDuration(wire[VideoGateway])
lazy val logDuration = MonitoringInterceptor.logDuration
[debug] duration - 15ms for gateways.VideoGateway#top()
[debug] duration - 5ms for gateways.PlayerGateway#findPlayer(2)
[debug] duration - 7ms for gateways.PlayerGateway#findPlayer(1)
[debug] duration - 4ms for gateways.PlayerGateway#findPlayer(3)
[debug] duration - 23ms for services.TopVideoService#topVideos()
Integration of macwire with Play 2.4
●
build.sbt:
libraryDependencies ++= Seq(
"com.softwaremill.macwire" %% "macros" %
"1.0.1",
"com.softwaremill.macwire" %% "runtime" %
"1.0.1")
routesGenerator :=
play.routes.compiler.InjectedRoutesGenerator
●
Customer loader in
application.conf:
play.application.loader=globals.TBAApplicationLo
ader
●
Custom loader:
package globals
import controllers.Assets
import play.api.ApplicationLoader.Context
import play.api._
import play.api.libs.ws.ning.NingWSComponents
import play.api.routing.Router
import router.Routes
class TBAApplicationLoader extends ApplicationLoader {
override def load(context: Context): Application = {
Logger.configure(context.environment)
(new BuiltInComponentsFromContext(context) with
TBAComponents).application
}
}
trait TBAComponents
extends BuiltInComponents // standard play components
with NingWSComponents // for wsClient
with TBAApplication {
import com.softwaremill.macwire._
lazy val assets: Assets = wire[Assets]
lazy val router: Router = wire[Routes] withPrefix "/"
}
Test application for IT tests
val context = ApplicationLoader.createContext(
new Environment(new File("."), ApplicationLoader.getClass.getClassLoader, Mode.Test))
class TBAApplicationLoaderMock extends ApplicationLoader {
override def load(context: Context): Application = {
new BuiltInComponentsFromContext(context) with TBAComponents {
override lazy val wsClient: WSClient = MockWS(SimulatedPlayerBackend.routes)
}.application
}
}
implicit val application = new TBAApplicationLoaderMock().load(context)
val server = TestServer(9000, application)
running(server) {
WsTestClient.withClient { ws ⇒
val response = await(ws.url(s"http://localhost:9000/player/$playerId").get())
response.status shouldEqual OK
}
}
The End
Questions?

More Related Content

What's hot

CPAN Packager
CPAN PackagerCPAN Packager
CPAN Packager
techmemo
 

What's hot (20)

EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
 
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWDEWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
 
CPAN Packager
CPAN PackagerCPAN Packager
CPAN Packager
 
Beyond AEM Curl Commands
Beyond AEM Curl CommandsBeyond AEM Curl Commands
Beyond AEM Curl Commands
 
EWD 3 Training Course Part 30: Modularising QEWD Applications
EWD 3 Training Course Part 30: Modularising QEWD ApplicationsEWD 3 Training Course Part 30: Modularising QEWD Applications
EWD 3 Training Course Part 30: Modularising QEWD Applications
 
App development with quasar (pdf)
App development with quasar (pdf)App development with quasar (pdf)
App development with quasar (pdf)
 
EWD 3 Training Course Part 12: QEWD Session Timeout Control
EWD 3 Training Course Part 12: QEWD Session Timeout ControlEWD 3 Training Course Part 12: QEWD Session Timeout Control
EWD 3 Training Course Part 12: QEWD Session Timeout Control
 
EWD 3 Training Course Part 11: Handling Errors in QEWD
EWD 3 Training Course Part 11: Handling Errors in QEWDEWD 3 Training Course Part 11: Handling Errors in QEWD
EWD 3 Training Course Part 11: Handling Errors in QEWD
 
EWD 3 Training Course Part 5a: First Steps in Building a QEWD Application
EWD 3 Training Course Part 5a: First Steps in Building a QEWD ApplicationEWD 3 Training Course Part 5a: First Steps in Building a QEWD Application
EWD 3 Training Course Part 5a: First Steps in Building a QEWD Application
 
Sprint 17
Sprint 17Sprint 17
Sprint 17
 
EWD 3 Training Course Part 2: EWD 3 Overview
EWD 3 Training Course Part 2: EWD 3 OverviewEWD 3 Training Course Part 2: EWD 3 Overview
EWD 3 Training Course Part 2: EWD 3 Overview
 
Performance tips for Symfony2 & PHP
Performance tips for Symfony2 & PHPPerformance tips for Symfony2 & PHP
Performance tips for Symfony2 & PHP
 
EWD 3 Training Course Part 29: Running QEWD as a Service
EWD 3 Training Course Part 29: Running QEWD as a ServiceEWD 3 Training Course Part 29: Running QEWD as a Service
EWD 3 Training Course Part 29: Running QEWD as a Service
 
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Servicesewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
 
EWD 3 Training Course Part 3: Summary of EWD 3 Modules
EWD 3 Training Course Part 3: Summary of EWD 3 ModulesEWD 3 Training Course Part 3: Summary of EWD 3 Modules
EWD 3 Training Course Part 3: Summary of EWD 3 Modules
 
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
 
EWD 3 Training Course Part 4: Installing & Configuring QEWD
EWD 3 Training Course Part 4: Installing & Configuring QEWDEWD 3 Training Course Part 4: Installing & Configuring QEWD
EWD 3 Training Course Part 4: Installing & Configuring QEWD
 
Symfony Under Control by Maxim Romanovsky
Symfony Under Control by Maxim RomanovskySymfony Under Control by Maxim Romanovsky
Symfony Under Control by Maxim Romanovsky
 
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4
 
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
 

Similar to Compile time dependency injection in Play 2.4 with macwire

Gr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx Plugin
Gr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx PluginGr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx Plugin
Gr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx Plugin
Yasuharu Nakano
 
Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Using and Customizing the Android Framework / part 4 of Embedded Android Work...Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Opersys inc.
 
JRuby on Rails Deployment: What They Didn't Tell You
JRuby on Rails Deployment: What They Didn't Tell YouJRuby on Rails Deployment: What They Didn't Tell You
JRuby on Rails Deployment: What They Didn't Tell You
elliando dias
 
Creating Scalable JVM/Java Apps on Heroku
Creating Scalable JVM/Java Apps on HerokuCreating Scalable JVM/Java Apps on Heroku
Creating Scalable JVM/Java Apps on Heroku
Joe Kutner
 

Similar to Compile time dependency injection in Play 2.4 with macwire (20)

Gradle como alternativa a maven
Gradle como alternativa a mavenGradle como alternativa a maven
Gradle como alternativa a maven
 
Towards Continuous Deployment with Django
Towards Continuous Deployment with DjangoTowards Continuous Deployment with Django
Towards Continuous Deployment with Django
 
VueJs Workshop
VueJs WorkshopVueJs Workshop
VueJs Workshop
 
Adopting GraalVM - Scale by the Bay 2018
Adopting GraalVM - Scale by the Bay 2018Adopting GraalVM - Scale by the Bay 2018
Adopting GraalVM - Scale by the Bay 2018
 
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
Testing Vue Apps with Cypress.io (STLJS Meetup April 2018)
 
Bootiful Reactive Testing with Mario Gray
Bootiful Reactive Testing with Mario GrayBootiful Reactive Testing with Mario Gray
Bootiful Reactive Testing with Mario Gray
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby Team
 
Gr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx Plugin
Gr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx PluginGr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx Plugin
Gr8conf EU 2013 Speed up your development: GroovyServ and Grails Improx Plugin
 
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
 
Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Using and Customizing the Android Framework / part 4 of Embedded Android Work...Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Using and Customizing the Android Framework / part 4 of Embedded Android Work...
 
Why Gradle?
Why Gradle?Why Gradle?
Why Gradle?
 
JRuby on Rails Deployment: What They Didn't Tell You
JRuby on Rails Deployment: What They Didn't Tell YouJRuby on Rails Deployment: What They Didn't Tell You
JRuby on Rails Deployment: What They Didn't Tell You
 
When Web Services Go Bad
When Web Services Go BadWhen Web Services Go Bad
When Web Services Go Bad
 
Set Up & Operate Tungsten Replicator
Set Up & Operate Tungsten ReplicatorSet Up & Operate Tungsten Replicator
Set Up & Operate Tungsten Replicator
 
Streaming in grails
Streaming in grailsStreaming in grails
Streaming in grails
 
DevSecCon London 2017 - MacOS security, hardening and forensics 101 by Ben Hu...
DevSecCon London 2017 - MacOS security, hardening and forensics 101 by Ben Hu...DevSecCon London 2017 - MacOS security, hardening and forensics 101 by Ben Hu...
DevSecCon London 2017 - MacOS security, hardening and forensics 101 by Ben Hu...
 
Sprockets
SprocketsSprockets
Sprockets
 
Creating Scalable JVM/Java Apps on Heroku
Creating Scalable JVM/Java Apps on HerokuCreating Scalable JVM/Java Apps on Heroku
Creating Scalable JVM/Java Apps on Heroku
 
Groovy In the Cloud
Groovy In the CloudGroovy In the Cloud
Groovy In the Cloud
 
Deployment Tactics
Deployment TacticsDeployment Tactics
Deployment Tactics
 

More from yann_s (7)

FS2 mongo reactivestreams
FS2 mongo reactivestreamsFS2 mongo reactivestreams
FS2 mongo reactivestreams
 
Bringing a public GraphQL API from the whiteboard to production
Bringing a public GraphQL API from the whiteboard to productionBringing a public GraphQL API from the whiteboard to production
Bringing a public GraphQL API from the whiteboard to production
 
Bringing a public GraphQL API from beta to production ready
Bringing a public GraphQL API from beta to production readyBringing a public GraphQL API from beta to production ready
Bringing a public GraphQL API from beta to production ready
 
Introduction to rust: a low-level language with high-level abstractions
Introduction to rust: a low-level language with high-level abstractionsIntroduction to rust: a low-level language with high-level abstractions
Introduction to rust: a low-level language with high-level abstractions
 
Performance optimisation with GraphQL
Performance optimisation with GraphQLPerformance optimisation with GraphQL
Performance optimisation with GraphQL
 
Introduction to GraphQL at API days
Introduction to GraphQL at API daysIntroduction to GraphQL at API days
Introduction to GraphQL at API days
 
Introduction to type classes in Scala
Introduction to type classes in ScalaIntroduction to type classes in Scala
Introduction to type classes in Scala
 

Recently uploaded

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Recently uploaded (20)

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 

Compile time dependency injection in Play 2.4 with macwire

  • 1. DI in Play 2.4 Compile time Dependency Injection with macwire Yann Simon
  • 3. Runtime vs compile time DI ● Runtime ✔ Support Lifecycle (start / stop) ● Compile time ✔ Dependency graph checked by compiler ✔ No runtime overhead
  • 5. Compile time DI ● With the cake pattern – Talk “Structure your Play application with the cake pattern (and test it)” ● Slides: http://de.slideshare.net/yann_s/play-withcake-export2 ● Video: http://www.ustream.tv/recorded/42775808 ● With constructor parameters
  • 6. DI with constructor parameters class Dependency1 class Dependency2 { def parse(input: String): Unit = println(s"parse '$input' with '$this'") } class Service(dep1: Dependency1, dep2: Dependency2) { def parse(input: String): Unit = dep2.parse(input) } val dep1 = new Dependency1 val dep2 = new Dependency2 val service = new Service(dep1, dep2)
  • 7. Singleton or not // singleton val dep1 = new Dependency1 val dep2 = new Dependency2 val service = new Service(dep1, dep2) // one instance per call val dep1 = new Dependency1 def dep2 = new Dependency2 def service = new Service(dep1, dep2)
  • 8. val or lazy val val dep1 = new Dependency1 val service = new Service(dep1, dep2) val dep2 = new Dependency2 java.lang.NullPointerException lazy val dep1 = new Dependency1 lazy val service = new Service(dep1, dep2) lazy val dep2 = new Dependency2
  • 9. Complex dependency tree lazy val dep1 = new Dependency1 lazy val dep2 = new Dependency2 lazy val dep3 = new Dependency3 lazy val dep4 = new Dependency4 lazy val dep5 = new Dependency5(dep3, dep4) lazy val dep6 = new Dependency6(dep2, dep4) lazy val dep7 = new Dependency7(dep5, dep6) lazy val service = new Service(dep1, dep2, dep3, dep4, dep7)
  • 10. With macwire import com.softwaremill.macwire._ lazy val dep1 = wire[Dependency1] lazy val dep2 = wire[Dependency2] lazy val dep3 = wire[Dependency3] lazy val dep4 = wire[Dependency4] lazy val dep5 = wire[Dependency5] lazy val dep6 = wire[Dependency6] lazy val dep7 = wire[Dependency7] lazy val service = wire[Service] And that's all!
  • 11. macwire ● Macwire resolves dependencies based on the type – Compile error when ambiguous – No good idea to have a String as dependency ;)
  • 12. Macwire ● https://github.com/adamw/macwire ● Other features – Accessing wired dynamically – Interceptors – Qualifiers
  • 13. Integration of macwire with Play ● Play 2.3 – Everything checked at compile time, expect... routing... :( ● Play 2.4 – Everything checked at compile time! – https://github.com/yanns/TPA/pull/1/files ● Demo
  • 14. Macwire interceptor ● Ex: monitor performance of ws calls: – MonitoringInterceptor lazy val videoGateway: VideoGateway = logDuration(wire[VideoGateway]) lazy val logDuration = MonitoringInterceptor.logDuration [debug] duration - 15ms for gateways.VideoGateway#top() [debug] duration - 5ms for gateways.PlayerGateway#findPlayer(2) [debug] duration - 7ms for gateways.PlayerGateway#findPlayer(1) [debug] duration - 4ms for gateways.PlayerGateway#findPlayer(3) [debug] duration - 23ms for services.TopVideoService#topVideos()
  • 15. Integration of macwire with Play 2.4 ● build.sbt: libraryDependencies ++= Seq( "com.softwaremill.macwire" %% "macros" % "1.0.1", "com.softwaremill.macwire" %% "runtime" % "1.0.1") routesGenerator := play.routes.compiler.InjectedRoutesGenerator ● Customer loader in application.conf: play.application.loader=globals.TBAApplicationLo ader ● Custom loader: package globals import controllers.Assets import play.api.ApplicationLoader.Context import play.api._ import play.api.libs.ws.ning.NingWSComponents import play.api.routing.Router import router.Routes class TBAApplicationLoader extends ApplicationLoader { override def load(context: Context): Application = { Logger.configure(context.environment) (new BuiltInComponentsFromContext(context) with TBAComponents).application } } trait TBAComponents extends BuiltInComponents // standard play components with NingWSComponents // for wsClient with TBAApplication { import com.softwaremill.macwire._ lazy val assets: Assets = wire[Assets] lazy val router: Router = wire[Routes] withPrefix "/" }
  • 16. Test application for IT tests val context = ApplicationLoader.createContext( new Environment(new File("."), ApplicationLoader.getClass.getClassLoader, Mode.Test)) class TBAApplicationLoaderMock extends ApplicationLoader { override def load(context: Context): Application = { new BuiltInComponentsFromContext(context) with TBAComponents { override lazy val wsClient: WSClient = MockWS(SimulatedPlayerBackend.routes) }.application } } implicit val application = new TBAApplicationLoaderMock().load(context) val server = TestServer(9000, application) running(server) { WsTestClient.withClient { ws ⇒ val response = await(ws.url(s"http://localhost:9000/player/$playerId").get()) response.status shouldEqual OK } }