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

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...Rob Tweed
 
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 QEWDRob Tweed
 
CPAN Packager
CPAN PackagerCPAN Packager
CPAN Packagertechmemo
 
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 ApplicationsRob Tweed
 
App development with quasar (pdf)
App development with quasar (pdf)App development with quasar (pdf)
App development with quasar (pdf)wonyong hwang
 
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 ControlRob Tweed
 
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 QEWDRob Tweed
 
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 ApplicationRob Tweed
 
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 OverviewRob Tweed
 
Performance tips for Symfony2 & PHP
Performance tips for Symfony2 & PHPPerformance tips for Symfony2 & PHP
Performance tips for Symfony2 & PHPMax Romanovsky
 
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 ServiceRob Tweed
 
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 ServicesRob Tweed
 
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 ModulesRob Tweed
 
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...Alexander Lisachenko
 
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 QEWDRob Tweed
 
Symfony Under Control by Maxim Romanovsky
Symfony Under Control by Maxim RomanovskySymfony Under Control by Maxim Romanovsky
Symfony Under Control by Maxim Romanovskyphp-user-group-minsk
 
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 4Rob Tweed
 
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 3Rob Tweed
 

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

Towards Continuous Deployment with Django
Towards Continuous Deployment with DjangoTowards Continuous Deployment with Django
Towards Continuous Deployment with DjangoRoger Barnes
 
VueJs Workshop
VueJs WorkshopVueJs Workshop
VueJs WorkshopUnfold UI
 
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 2018Petr Zapletal
 
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)Christian Catalan
 
Bootiful Reactive Testing with Mario Gray
Bootiful Reactive Testing with Mario GrayBootiful Reactive Testing with Mario Gray
Bootiful Reactive Testing with Mario GrayVMware Tanzu
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby TeamArto Artnik
 
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 PluginYasuharu Nakano
 
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)DECK36
 
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 Youelliando dias
 
When Web Services Go Bad
When Web Services Go BadWhen Web Services Go Bad
When Web Services Go BadSteve Loughran
 
Set Up & Operate Tungsten Replicator
Set Up & Operate Tungsten ReplicatorSet Up & Operate Tungsten Replicator
Set Up & Operate Tungsten ReplicatorContinuent
 
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...DevSecCon
 
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 HerokuJoe Kutner
 
Groovy In the Cloud
Groovy In the CloudGroovy In the Cloud
Groovy In the CloudJim Driscoll
 
Deployment Tactics
Deployment TacticsDeployment Tactics
Deployment TacticsIan Barber
 

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

FS2 mongo reactivestreams
FS2 mongo reactivestreamsFS2 mongo reactivestreams
FS2 mongo reactivestreamsyann_s
 
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 productionyann_s
 
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 readyyann_s
 
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 abstractionsyann_s
 
Performance optimisation with GraphQL
Performance optimisation with GraphQLPerformance optimisation with GraphQL
Performance optimisation with GraphQLyann_s
 
Introduction to GraphQL at API days
Introduction to GraphQL at API daysIntroduction to GraphQL at API days
Introduction to GraphQL at API daysyann_s
 
Introduction to type classes in Scala
Introduction to type classes in ScalaIntroduction to type classes in Scala
Introduction to type classes in Scalayann_s
 

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

Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbuapidays
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
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 WorkerThousandEyes
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...apidays
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 

Recently uploaded (20)

Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
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
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 

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 } }