SlideShare ist ein Scribd-Unternehmen logo
1 von 43
Downloaden Sie, um offline zu lesen
The no-framework Scala
Dependency Injection
framework
11/12/2013 BuildStuff 2013

Adam Warski

@adamwarski
BuildStuff 2013
You don’t need anything special to
do Dependency Injection

11/12/2013 BuildStuff 2013

@adamwarski
We often over-complicate

11/12/2013 BuildStuff 2013

@adamwarski
Who Am I?
❖

Day: coding @ SoftwareMill!

❖

Afternoon: playgrounds, Duplos, etc.!

❖

Evenings: blogging, open-source!
❖

Original author of Hibernate Envers!

❖

ElasticMQ, Veripacks, MacWire!

❖

http://www.warski.org

11/12/2013 BuildStuff 2013

@adamwarski
What is Dependency
Injection?

11/12/2013 BuildStuff 2013

@adamwarski
What is DI?
class PresentPackager {!
! def wrap() {!
! ! new RibbonSelector().selectRandom()!
! ! …!
} !
}
11/12/2013 BuildStuff 2013

@adamwarski
What is DI?
class PresentPackager(rs: RibbonSelector) {!
! def wrap() {!
! ! rs.selectRandom()!
! ! …!
} !
}
11/12/2013 BuildStuff 2013

@adamwarski
Yes, DI is just using parameters

11/12/2013 BuildStuff 2013

@adamwarski
Why?
❖

Restrict the knowledge of the class

class PresentPackager {




class PresentPackager

! (rs: RibbonSelector) {


!
!
!
!
!
}

def wrap() {

! new RibbonSelector()

! ! .selectRandom()

! …

}


11/12/2013 BuildStuff 2013



!
!
!
!
}

def wrap() {

! rs.selectRandom()

! …

}


@adamwarski
But still …

❖

We need to have the news somewhere

11/12/2013 BuildStuff 2013

@adamwarski
Let’s create a DI container!
a.k.a. framework

11/12/2013 BuildStuff 2013

@adamwarski
DI in Java
❖

Many frameworks!

❖

Configuration via:!
❖

XML!

❖

annotations!

❖

Java

11/12/2013 BuildStuff 2013

@adamwarski
What’s wrong with that?

❖

Do I really need a DI framework?

11/12/2013 BuildStuff 2013

@adamwarski
Let’s go back …

❖

… and just use our host language!

❖

in this case, Scala!

❖

mapping DI framework concepts to native language
constructs

11/12/2013 BuildStuff 2013

@adamwarski
Manual DI!
!

object PresentWrapper extends App {!
!
!

val ribbonSelector = 

! ! ! new RibbonSelector()!

!
!

val wrappingPaperFeeder = 

! ! ! new WrappingPaperFeeder()!

!
!
!
!

val presentPackager = 

! ! ! new PresentPackager(

! ! ! ! ribbonSelector, 

! ! ! ! wrappingPaperFeeder)!

}
11/12/2013 BuildStuff 2013

@adamwarski
Manual DI!
!

object PresentWrapper extends App {!
!
!

lazy val ribbonSelector = 

! ! ! new RibbonSelector()!

!
!

lazy val wrappingPaperFeeder = 

! ! ! new WrappingPaperFeeder()!

!
!
!
!

lazy
! !
! !
! !

val presentPackager = 

! new PresentPackager(

! ! ribbonSelector, 

! ! wrappingPaperFeeder)!

}
11/12/2013 BuildStuff 2013

@adamwarski
MacWire
import com.softwaremill.macwire.MacwireMacros._!
object PresentWrapper extends App {!
!
!

lazy val ribbonSelector = 

! ! ! wire[RibbonSelector]!

!
!

lazy val wrappingPaperFeeder =

! ! ! wire[WrappingPaperFeeder]!

!
!

lazy val presentPackager =

! ! ! wire[PresentPackager]




}
11/12/2013 BuildStuff 2013

@adamwarski
Side-note: 

Scala Macros

11/12/2013 BuildStuff 2013

@adamwarski
Side-note: Scala Macros

❖

Scala code executed at compile time!

❖

Operate on trees!

❖

Can inspect the environment, generate code!
❖

the code is type-checked

11/12/2013 BuildStuff 2013

@adamwarski
Side-note: Scala Macros
❖

E.g. debug macro!

def debug(params: Any*) = macro debug_impl!
def debug_impl

! ! ! (c: Context)

! ! ! (params: c.Expr[Any]*): c.Expr[Unit]!
!

debug(presentCount) ⟹!
! println(“presentCount = “ + presentCount)
11/12/2013 BuildStuff 2013

@adamwarski
Side-note: Scala Macros
❖

Debug macro implementation!

import c.universe._!
val paramRep = show(param.tree)

val paramRepTree = Literal(Constant(paramRep))

val paramRepExpr = c.Expr[String](paramRepTree)!
reify { println(

! paramRepExpr.splice + 

! " = " + 

! param.splice) }
11/12/2013 BuildStuff 2013

@adamwarski
Side-note: Scala Macros
❖

MacWire!

def wire[T] = macro wire_impl[T]!
def wire_impl

! ! ! [T: c.WeakTypeTag]

! ! ! (c: Context): c.Expr[T]

11/12/2013 BuildStuff 2013

@adamwarski
MacWire
import com.softwaremill.macwire.MacwireMacros._!
object PresentWrapper extends App {!
! lazy val ribbonSelector = 

! ! ! ! wire[RibbonSelector]!
! lazy val wrappingPaperFeeder =

! ! ! ! wire[WrappingPaperFeeder]!
! lazy val presentPackager =

! ! ! ! wire[PresentPackager]

}
11/12/2013 BuildStuff 2013

@adamwarski
Scopes

❖

How long will an object (instance) live?

11/12/2013 BuildStuff 2013

@adamwarski
Singleton & dependent
object NorthPole extends App {!
! // Singleton!
lazy val santaClaus = wire[SantaClaus]!
!

! // Dependent!
def gnome = wire[Gnome]!
}
11/12/2013 BuildStuff 2013

@adamwarski
Arbitrary scopes
trait WebFrontEnd {

! lazy val loggedInUser = 

! ! session(new LoggedInUser)



! def session: Scope

}!
!

trait Scope {

! def apply(factory: => T): T

}
11/12/2013 BuildStuff 2013

@adamwarski
Arbitrary scopes
object MyApp extends WebFrontEnd {

! val session: Scope = 

! ! ! ! new ThreadLocalScope()!
! val filter = new ScopeFilter(session)



! // bootstrap the web server 

! // using the filter

}
11/12/2013 BuildStuff 2013

@adamwarski
Arbitrary scopes
class ScopeFilter(sessionScope: ThreadLocalScope) 

! ! ! extends Filter {!
! def doFilter(request: ServletRequest) {

! ! sessionScope

! ! ! .withStorage(request.getSession()) {!
! ! ! request.proceed()!
! ! }

! }

}
11/12/2013 BuildStuff 2013

@adamwarski
Modules
❖

Pre-wired!

❖

Composable!

❖

Dependencies!

❖

Module per package?!
❖

Veripacks :)

11/12/2013 BuildStuff 2013

@adamwarski
Modules

❖

Module: trait!

❖

Pre-wired: new, MacWire!

❖

Composable: extends/with!

❖

Dependencies: extends/with / abstract members

11/12/2013 BuildStuff 2013

@adamwarski
Modules
trait PresentWrapper {!
! lazy val ribbonSelector = 

! ! ! ! wire[RibbonSelector]!
! lazy val wrappingPaperFeeder =

! ! ! ! wire[WrappingPaperFeeder]!
lazy val presentPackager =

! ! ! ! wire[PresentPackager]!
}
11/12/2013 BuildStuff 2013

@adamwarski
Modules
trait PresentFactory extends PresentWrapper {!
! lazy val teddyBearProvider = 

! ! ! ! wire[TeddyBearProvider]!
! lazy val toyTrainProvider =

! ! ! ! wire[ToyTrainProvider]!
lazy val presentAssembly =

! ! ! ! wire[PresentAssembly]!
}
11/12/2013 BuildStuff 2013

@adamwarski
Modules
trait HomeOfSanta {!
! lazy val santaClaus = wire[SantaClaus]!
! lazy val rudolf = wire[Rudolf]!
! lazy val fireplace = wire[Fireplace]!
!

def presentAssembly: PresentAssembly!
}
11/12/2013 BuildStuff 2013

@adamwarski
Modules
trait PresentWrapper { … }

trait PresentFactory extends PresentWrapper { }

trait HomeOfSanta { … }!
!

object NorthPole 

! extends PresentWrapper 

!
with PresentFactory 

!
with HomeOfSanta {!
! santaClaus.deliver()!
}
11/12/2013 BuildStuff 2013

@adamwarski
Testing Santa’s Home
class HomeOfSantaTest extends FlatSpec {!
! it should “deliver presents” in {!
! ! val mockPresentAssembly = …!
! ! new HomeOfSanta {!
!! lazy val presentAssembly = 

! ! ! ! mockPresentAssembly }!
! ! …!
! }!
}
11/12/2013 BuildStuff 2013

@adamwarski
Cake Pattern
trait PresentPackagerModule {!
!
!
!
!
!
!

class PresentPackager {

! def wrap() {

! ! ribbonSelector.selectRandom()

! ! …

! }

}


! lazy val presentPackager = new PresentPackager()

! def ribbonSelector: RibbonSelector

}
11/12/2013 BuildStuff 2013

@adamwarski
Cake Pattern
val cake = new PresentPackagerModule

! with RibbonSelectorModule

! with WrappingPaperFeederModule

! with TeddyBearProviderModule

! with ToyTrainProviderModule

! with PresentAssemblyModule

! with … { }

11/12/2013 BuildStuff 2013

@adamwarski
Other features
❖

Interceptors!
!

trait Chimney {!
! lazy val presentTransferer =

! ! transactional(wire[PresentTransferer])!
! def transactional: Interceptor!
}
11/12/2013 BuildStuff 2013

@adamwarski
Other features
❖

Factories!
❖

a dedicated object or …!

!

trait PresentBoxer {!
! def box(size: Size) = wire[Box]!
}
11/12/2013 BuildStuff 2013

@adamwarski
Other features
❖

Instance maps!
❖

for integrating e.g. with Play!

❖

Factories!

❖

In-method wiring!

❖

More coming, someday :)

11/12/2013 BuildStuff 2013

@adamwarski
Summing up
❖

Reconsider using a framework!

❖

Native Scala gives a lot of power!
❖
❖

❖

use it!
wisely!

More flexibility (less constraints)

11/12/2013 BuildStuff 2013

@adamwarski
Links

❖

http://www.warski.org!

❖

https://github.com/adamw/macwire!

❖

http://springsource.com/

11/12/2013 BuildStuff 2013

@adamwarski
Thanks!

❖

Questions?!

❖

Stickers ->!

❖

adam@warski.org

11/12/2013 BuildStuff 2013

@adamwarski

Weitere ähnliche Inhalte

Was ist angesagt?

component: ruby gems for the browser
component: ruby gems for the browsercomponent: ruby gems for the browser
component: ruby gems for the browser
Timothy Oxley
 
Javascript Libraries
Javascript LibrariesJavascript Libraries
Javascript Libraries
elliando dias
 
Re-Introduction to Third-party Scripting
Re-Introduction to Third-party ScriptingRe-Introduction to Third-party Scripting
Re-Introduction to Third-party Scripting
benvinegar
 

Was ist angesagt? (15)

The Inclusive Web: hands-on with HTML5 and jQuery
The Inclusive Web: hands-on with HTML5 and jQueryThe Inclusive Web: hands-on with HTML5 and jQuery
The Inclusive Web: hands-on with HTML5 and jQuery
 
遇見 Ruby on Rails
遇見 Ruby on Rails遇見 Ruby on Rails
遇見 Ruby on Rails
 
Web Ninja
Web NinjaWeb Ninja
Web Ninja
 
component: ruby gems for the browser
component: ruby gems for the browsercomponent: ruby gems for the browser
component: ruby gems for the browser
 
Rails traps
Rails trapsRails traps
Rails traps
 
1.6 米嘉 gobuildweb
1.6 米嘉 gobuildweb1.6 米嘉 gobuildweb
1.6 米嘉 gobuildweb
 
Web development basics (Part-2)
Web development basics (Part-2)Web development basics (Part-2)
Web development basics (Part-2)
 
Best Practices - Mobile Developer Summit
Best Practices - Mobile Developer SummitBest Practices - Mobile Developer Summit
Best Practices - Mobile Developer Summit
 
Rails Girls: Programming, Web Applications and Ruby on Rails
Rails Girls: Programming, Web Applications and Ruby on RailsRails Girls: Programming, Web Applications and Ruby on Rails
Rails Girls: Programming, Web Applications and Ruby on Rails
 
Introduction to python
Introduction to pythonIntroduction to python
Introduction to python
 
How does the Internet Work?
How does the Internet Work?How does the Internet Work?
How does the Internet Work?
 
Javascript Libraries
Javascript LibrariesJavascript Libraries
Javascript Libraries
 
Rapid prototyping with solr - By Erik Hatcher
Rapid prototyping with solr -  By Erik Hatcher Rapid prototyping with solr -  By Erik Hatcher
Rapid prototyping with solr - By Erik Hatcher
 
JavaScript!
JavaScript!JavaScript!
JavaScript!
 
Re-Introduction to Third-party Scripting
Re-Introduction to Third-party ScriptingRe-Introduction to Third-party Scripting
Re-Introduction to Third-party Scripting
 

Ähnlich wie The no-framework Scala Dependency Injection Framework

Ähnlich wie The no-framework Scala Dependency Injection Framework (20)

Using Ember to Make a Bazillion Dollars
Using Ember to Make a Bazillion DollarsUsing Ember to Make a Bazillion Dollars
Using Ember to Make a Bazillion Dollars
 
Solid and Sustainable Development in Scala
Solid and Sustainable Development in ScalaSolid and Sustainable Development in Scala
Solid and Sustainable Development in Scala
 
Solid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaSolid And Sustainable Development in Scala
Solid And Sustainable Development in Scala
 
Beginning Scala with Skinny Framework #jjug_ccc
Beginning Scala with Skinny Framework #jjug_cccBeginning Scala with Skinny Framework #jjug_ccc
Beginning Scala with Skinny Framework #jjug_ccc
 
Lasso and Couchdb : the happy couple
Lasso and Couchdb : the happy coupleLasso and Couchdb : the happy couple
Lasso and Couchdb : the happy couple
 
Lessons I Learned While Scaling to 5000 Puppet Agents
Lessons I Learned While Scaling to 5000 Puppet AgentsLessons I Learned While Scaling to 5000 Puppet Agents
Lessons I Learned While Scaling to 5000 Puppet Agents
 
.NET Development for SQL Server Developer
.NET Development for SQL Server Developer.NET Development for SQL Server Developer
.NET Development for SQL Server Developer
 
Cassandra Meetup: Real-time Analytics using Cassandra, Spark and Shark at Ooyala
Cassandra Meetup: Real-time Analytics using Cassandra, Spark and Shark at OoyalaCassandra Meetup: Real-time Analytics using Cassandra, Spark and Shark at Ooyala
Cassandra Meetup: Real-time Analytics using Cassandra, Spark and Shark at Ooyala
 
DocuOps & Asciidoctor in a JVM World
DocuOps & Asciidoctor in a JVM WorldDocuOps & Asciidoctor in a JVM World
DocuOps & Asciidoctor in a JVM World
 
The Modern Java Web Developer Bootcamp - Devoxx 2013
The Modern Java Web Developer Bootcamp - Devoxx 2013The Modern Java Web Developer Bootcamp - Devoxx 2013
The Modern Java Web Developer Bootcamp - Devoxx 2013
 
Sprockets
SprocketsSprockets
Sprockets
 
Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!
 
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
 
Modern Front-End Development
Modern Front-End DevelopmentModern Front-End Development
Modern Front-End Development
 
MongoTalk/Voyage
MongoTalk/VoyageMongoTalk/Voyage
MongoTalk/Voyage
 
ACCU 2013 Taking Scala into the Enterpise
ACCU 2013 Taking Scala into the EnterpiseACCU 2013 Taking Scala into the Enterpise
ACCU 2013 Taking Scala into the Enterpise
 
From Hacker to Programmer (w/ Webpack, Babel and React)
From Hacker to Programmer (w/ Webpack, Babel and React)From Hacker to Programmer (w/ Webpack, Babel and React)
From Hacker to Programmer (w/ Webpack, Babel and React)
 
The nightmare of locking, blocking and deadlocking. SQLSaturday #257, Verona
The nightmare of locking, blocking and deadlocking. SQLSaturday #257, VeronaThe nightmare of locking, blocking and deadlocking. SQLSaturday #257, Verona
The nightmare of locking, blocking and deadlocking. SQLSaturday #257, Verona
 
When Sightly Meets Slice by Tomasz Niedźwiedź
When Sightly Meets Slice by Tomasz NiedźwiedźWhen Sightly Meets Slice by Tomasz Niedźwiedź
When Sightly Meets Slice by Tomasz Niedźwiedź
 
Refresh OKC
Refresh OKCRefresh OKC
Refresh OKC
 

Mehr von Adam Warski

Mehr von Adam Warski (8)

What have the annotations done to us?
What have the annotations done to us?What have the annotations done to us?
What have the annotations done to us?
 
Hejdyk maleńka część mazur
Hejdyk maleńka część mazurHejdyk maleńka część mazur
Hejdyk maleńka część mazur
 
Slick eventsourcing
Slick eventsourcingSlick eventsourcing
Slick eventsourcing
 
Evaluating persistent, replicated message queues
Evaluating persistent, replicated message queuesEvaluating persistent, replicated message queues
Evaluating persistent, replicated message queues
 
ElasticMQ: a fully asynchronous, Akka-based SQS server
ElasticMQ: a fully asynchronous, Akka-based SQS serverElasticMQ: a fully asynchronous, Akka-based SQS server
ElasticMQ: a fully asynchronous, Akka-based SQS server
 
Recommendation systems with Mahout: introduction
Recommendation systems with Mahout: introductionRecommendation systems with Mahout: introduction
Recommendation systems with Mahout: introduction
 
Scala Macros
Scala MacrosScala Macros
Scala Macros
 
CDI Portable Extensions
CDI Portable ExtensionsCDI Portable Extensions
CDI Portable Extensions
 

Kürzlich hochgeladen

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
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Kürzlich hochgeladen (20)

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
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
 
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
 
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
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
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
 
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
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
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
 
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
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 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...
 
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
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
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
 

The no-framework Scala Dependency Injection Framework

  • 1. The no-framework Scala Dependency Injection framework 11/12/2013 BuildStuff 2013 Adam Warski
 @adamwarski BuildStuff 2013
  • 2. You don’t need anything special to do Dependency Injection 11/12/2013 BuildStuff 2013 @adamwarski
  • 3. We often over-complicate 11/12/2013 BuildStuff 2013 @adamwarski
  • 4. Who Am I? ❖ Day: coding @ SoftwareMill! ❖ Afternoon: playgrounds, Duplos, etc.! ❖ Evenings: blogging, open-source! ❖ Original author of Hibernate Envers! ❖ ElasticMQ, Veripacks, MacWire! ❖ http://www.warski.org 11/12/2013 BuildStuff 2013 @adamwarski
  • 5. What is Dependency Injection? 11/12/2013 BuildStuff 2013 @adamwarski
  • 6. What is DI? class PresentPackager {! ! def wrap() {! ! ! new RibbonSelector().selectRandom()! ! ! …! } ! } 11/12/2013 BuildStuff 2013 @adamwarski
  • 7. What is DI? class PresentPackager(rs: RibbonSelector) {! ! def wrap() {! ! ! rs.selectRandom()! ! ! …! } ! } 11/12/2013 BuildStuff 2013 @adamwarski
  • 8. Yes, DI is just using parameters 11/12/2013 BuildStuff 2013 @adamwarski
  • 9. Why? ❖ Restrict the knowledge of the class class PresentPackager {
 
 class PresentPackager
 ! (rs: RibbonSelector) {
 ! ! ! ! ! } def wrap() {
 ! new RibbonSelector()
 ! ! .selectRandom()
 ! …
 }
 11/12/2013 BuildStuff 2013 
 ! ! ! ! } def wrap() {
 ! rs.selectRandom()
 ! …
 }
 @adamwarski
  • 10. But still … ❖ We need to have the news somewhere 11/12/2013 BuildStuff 2013 @adamwarski
  • 11. Let’s create a DI container! a.k.a. framework 11/12/2013 BuildStuff 2013 @adamwarski
  • 12. DI in Java ❖ Many frameworks! ❖ Configuration via:! ❖ XML! ❖ annotations! ❖ Java 11/12/2013 BuildStuff 2013 @adamwarski
  • 13. What’s wrong with that? ❖ Do I really need a DI framework? 11/12/2013 BuildStuff 2013 @adamwarski
  • 14. Let’s go back … ❖ … and just use our host language! ❖ in this case, Scala! ❖ mapping DI framework concepts to native language constructs 11/12/2013 BuildStuff 2013 @adamwarski
  • 15. Manual DI! ! object PresentWrapper extends App {! ! ! val ribbonSelector = 
 ! ! ! new RibbonSelector()! ! ! val wrappingPaperFeeder = 
 ! ! ! new WrappingPaperFeeder()! ! ! ! ! val presentPackager = 
 ! ! ! new PresentPackager(
 ! ! ! ! ribbonSelector, 
 ! ! ! ! wrappingPaperFeeder)! } 11/12/2013 BuildStuff 2013 @adamwarski
  • 16. Manual DI! ! object PresentWrapper extends App {! ! ! lazy val ribbonSelector = 
 ! ! ! new RibbonSelector()! ! ! lazy val wrappingPaperFeeder = 
 ! ! ! new WrappingPaperFeeder()! ! ! ! ! lazy ! ! ! ! ! ! val presentPackager = 
 ! new PresentPackager(
 ! ! ribbonSelector, 
 ! ! wrappingPaperFeeder)! } 11/12/2013 BuildStuff 2013 @adamwarski
  • 17. MacWire import com.softwaremill.macwire.MacwireMacros._! object PresentWrapper extends App {! ! ! lazy val ribbonSelector = 
 ! ! ! wire[RibbonSelector]! ! ! lazy val wrappingPaperFeeder =
 ! ! ! wire[WrappingPaperFeeder]! ! ! lazy val presentPackager =
 ! ! ! wire[PresentPackager]
 
 } 11/12/2013 BuildStuff 2013 @adamwarski
  • 18. Side-note: 
 Scala Macros 11/12/2013 BuildStuff 2013 @adamwarski
  • 19. Side-note: Scala Macros ❖ Scala code executed at compile time! ❖ Operate on trees! ❖ Can inspect the environment, generate code! ❖ the code is type-checked 11/12/2013 BuildStuff 2013 @adamwarski
  • 20. Side-note: Scala Macros ❖ E.g. debug macro! def debug(params: Any*) = macro debug_impl! def debug_impl
 ! ! ! (c: Context)
 ! ! ! (params: c.Expr[Any]*): c.Expr[Unit]! ! debug(presentCount) ⟹! ! println(“presentCount = “ + presentCount) 11/12/2013 BuildStuff 2013 @adamwarski
  • 21. Side-note: Scala Macros ❖ Debug macro implementation! import c.universe._! val paramRep = show(param.tree)
 val paramRepTree = Literal(Constant(paramRep))
 val paramRepExpr = c.Expr[String](paramRepTree)! reify { println(
 ! paramRepExpr.splice + 
 ! " = " + 
 ! param.splice) } 11/12/2013 BuildStuff 2013 @adamwarski
  • 22. Side-note: Scala Macros ❖ MacWire! def wire[T] = macro wire_impl[T]! def wire_impl
 ! ! ! [T: c.WeakTypeTag]
 ! ! ! (c: Context): c.Expr[T] 11/12/2013 BuildStuff 2013 @adamwarski
  • 23. MacWire import com.softwaremill.macwire.MacwireMacros._! object PresentWrapper extends App {! ! lazy val ribbonSelector = 
 ! ! ! ! wire[RibbonSelector]! ! lazy val wrappingPaperFeeder =
 ! ! ! ! wire[WrappingPaperFeeder]! ! lazy val presentPackager =
 ! ! ! ! wire[PresentPackager]
 } 11/12/2013 BuildStuff 2013 @adamwarski
  • 24. Scopes ❖ How long will an object (instance) live? 11/12/2013 BuildStuff 2013 @adamwarski
  • 25. Singleton & dependent object NorthPole extends App {! ! // Singleton! lazy val santaClaus = wire[SantaClaus]! ! ! // Dependent! def gnome = wire[Gnome]! } 11/12/2013 BuildStuff 2013 @adamwarski
  • 26. Arbitrary scopes trait WebFrontEnd {
 ! lazy val loggedInUser = 
 ! ! session(new LoggedInUser)
 
 ! def session: Scope
 }! ! trait Scope {
 ! def apply(factory: => T): T
 } 11/12/2013 BuildStuff 2013 @adamwarski
  • 27. Arbitrary scopes object MyApp extends WebFrontEnd {
 ! val session: Scope = 
 ! ! ! ! new ThreadLocalScope()! ! val filter = new ScopeFilter(session)
 
 ! // bootstrap the web server 
 ! // using the filter
 } 11/12/2013 BuildStuff 2013 @adamwarski
  • 28. Arbitrary scopes class ScopeFilter(sessionScope: ThreadLocalScope) 
 ! ! ! extends Filter {! ! def doFilter(request: ServletRequest) {
 ! ! sessionScope
 ! ! ! .withStorage(request.getSession()) {! ! ! ! request.proceed()! ! ! }
 ! }
 } 11/12/2013 BuildStuff 2013 @adamwarski
  • 30. Modules ❖ Module: trait! ❖ Pre-wired: new, MacWire! ❖ Composable: extends/with! ❖ Dependencies: extends/with / abstract members 11/12/2013 BuildStuff 2013 @adamwarski
  • 31. Modules trait PresentWrapper {! ! lazy val ribbonSelector = 
 ! ! ! ! wire[RibbonSelector]! ! lazy val wrappingPaperFeeder =
 ! ! ! ! wire[WrappingPaperFeeder]! lazy val presentPackager =
 ! ! ! ! wire[PresentPackager]! } 11/12/2013 BuildStuff 2013 @adamwarski
  • 32. Modules trait PresentFactory extends PresentWrapper {! ! lazy val teddyBearProvider = 
 ! ! ! ! wire[TeddyBearProvider]! ! lazy val toyTrainProvider =
 ! ! ! ! wire[ToyTrainProvider]! lazy val presentAssembly =
 ! ! ! ! wire[PresentAssembly]! } 11/12/2013 BuildStuff 2013 @adamwarski
  • 33. Modules trait HomeOfSanta {! ! lazy val santaClaus = wire[SantaClaus]! ! lazy val rudolf = wire[Rudolf]! ! lazy val fireplace = wire[Fireplace]! ! def presentAssembly: PresentAssembly! } 11/12/2013 BuildStuff 2013 @adamwarski
  • 34. Modules trait PresentWrapper { … }
 trait PresentFactory extends PresentWrapper { }
 trait HomeOfSanta { … }! ! object NorthPole 
 ! extends PresentWrapper 
 ! with PresentFactory 
 ! with HomeOfSanta {! ! santaClaus.deliver()! } 11/12/2013 BuildStuff 2013 @adamwarski
  • 35. Testing Santa’s Home class HomeOfSantaTest extends FlatSpec {! ! it should “deliver presents” in {! ! ! val mockPresentAssembly = …! ! ! new HomeOfSanta {! !! lazy val presentAssembly = 
 ! ! ! ! mockPresentAssembly }! ! ! …! ! }! } 11/12/2013 BuildStuff 2013 @adamwarski
  • 36. Cake Pattern trait PresentPackagerModule {! ! ! ! ! ! ! class PresentPackager {
 ! def wrap() {
 ! ! ribbonSelector.selectRandom()
 ! ! …
 ! }
 }
 ! lazy val presentPackager = new PresentPackager()
 ! def ribbonSelector: RibbonSelector
 } 11/12/2013 BuildStuff 2013 @adamwarski
  • 37. Cake Pattern val cake = new PresentPackagerModule
 ! with RibbonSelectorModule
 ! with WrappingPaperFeederModule
 ! with TeddyBearProviderModule
 ! with ToyTrainProviderModule
 ! with PresentAssemblyModule
 ! with … { } 11/12/2013 BuildStuff 2013 @adamwarski
  • 38. Other features ❖ Interceptors! ! trait Chimney {! ! lazy val presentTransferer =
 ! ! transactional(wire[PresentTransferer])! ! def transactional: Interceptor! } 11/12/2013 BuildStuff 2013 @adamwarski
  • 39. Other features ❖ Factories! ❖ a dedicated object or …! ! trait PresentBoxer {! ! def box(size: Size) = wire[Box]! } 11/12/2013 BuildStuff 2013 @adamwarski
  • 40. Other features ❖ Instance maps! ❖ for integrating e.g. with Play! ❖ Factories! ❖ In-method wiring! ❖ More coming, someday :) 11/12/2013 BuildStuff 2013 @adamwarski
  • 41. Summing up ❖ Reconsider using a framework! ❖ Native Scala gives a lot of power! ❖ ❖ ❖ use it! wisely! More flexibility (less constraints) 11/12/2013 BuildStuff 2013 @adamwarski