Slide 1

Slide 1 text

Dependency  injec+on  in  Scala   The sequel - SubCut javaBin, Trondheim – 1.12.2011

Slide 2

Slide 2 text

SubCut   Scala  Uniquely  Bound  Classes  Under  Traits  

Slide 3

Slide 3 text

History  lesson   SubCut   (My  personal)  Crystal  Ball   Scala  Uniquely  Bound  Classes  Under  Traits  

Slide 4

Slide 4 text

History  lesson   Constructor  injec+on   Cake  pa?ern   new SomeClass(dep1, dep2) …  

Slide 5

Slide 5 text

trait SomeComponent { val aThing: SomeInterface trait SomeInterface { // Stuff } } trait AnotherComponentImpl extends AnotherComponent { this: SomeComponent => def myMethod { aThing.usefulStuff() } }   object ComponentRegistry extends AnotherComponentImpl with SomeComponentImpl { val aThing = new MyFavouriteImpl }

Slide 6

Slide 6 text

Let’s  (Sub)Cut  to  it  

Slide 7

Slide 7 text

object ProjectConfiguration extends NewBindingModule({ module => import module._ // can now use bind directly bind [UserRepository] toInstance new RealUserRepository bind [Analyzer] identifiedBy 'webAnalyzer to instanceOfClass [WebAnalyzer] bind [Session] identifiedBy 'currentUser toProvider { WebServerSession.getCurrentUser().getSession() } bind [Int] identifiedBy 'maxThreadPoolSize toInstance 10 bind [WebSearch] toLazyInstance { new GoogleSearchService()(ProjectConfiguration) } ... }) Configura+on  module  

Slide 8

Slide 8 text

Injectable  class   object ProjectConfiguration extends NewBindingModule({ module => ... }) class UserService(val serviceId: String, webAnalyzer: Option[Analyzer] = injected) (implicit val bindingModule: BindingModule) extends Injectable { val userRepository = inject[UserRepository] val maxPoolSize = injectIfBound[Int]('maxThreadPoolSize) { 15 } val myAnalyzer = injectIfMissing[Analyzer](webAnalyzer) ... }

Slide 9

Slide 9 text

Configuring  your  app   implicit val bindingModule = ProjectConfiguration val topInstance = new UserService("myUserService")

Slide 10

Slide 10 text

Configuring  your  app   implicit val bindingModule = ProjectConfiguration val topInstance = new UserService("myUserService") val topInstance = new UserService("myUserService")(ProjectConfiguration)

Slide 11

Slide 11 text

Configuring  your  app   implicit val bindingModule = ProjectConfiguration val topInstance = new UserService("myUserService") val topInstance = new UserService("myUserService")(ProjectConfiguration) trait ProjectBindings { implicit val bindingModule: BindingModule = ProjectConfiguration } class MyApp extends Injectable with ProjectBindings { // ... }

Slide 12

Slide 12 text

Configuring  your  app   implicit val bindingModule = ProjectConfiguration val topInstance = new UserService("myUserService") val topInstance = new UserService("myUserService")(ProjectConfiguration) class SomePage(implicit val bindingModule: BindingModule) extends WicketPage with Injectable { } class ProdSomePage extends SomePage(ProjectConfiguration) trait ProjectBindings { implicit val bindingModule: BindingModule = ProjectConfiguration } class MyApp extends Injectable with ProjectBindings { // ... }

Slide 13

Slide 13 text

Tes+ng   test(”SubCut scalatest test 1") { ProjectConfiguration.modifyBindings { module => // new calls to bind inside here val service = new UserService("myUserService")(module) // all testcode using service also goes inside here } }

Slide 14

Slide 14 text

Tes+ng   val testConfig = ProjectConfiguration.modifyBindings { module => // new calls to bind inside here module } val service = new UserService(“myOtherService”)(testConfig) test(”SubCut scalatest test 2") { // testcode using service goes here } test(”SubCut scalatest test 1") { ProjectConfiguration.modifyBindings { module => // new calls to bind inside here val service = new UserService("myUserService")(module) // all testcode using service also goes inside here } }

Slide 15

Slide 15 text

Tes+ng   val testModule = TestProjectConfiguration :: ProjectConfiguration val mergedService = new UserService("myMergedService")(testModule) test(”SubCut scalatest test 3") { // testcode using mergedService goes here } val testConfig = ProjectConfiguration.modifyBindings { module => // new calls to bind inside here module } val service = new UserService(“myOtherService”)(testConfig) test(”SubCut scalatest test 2") { // testcode using service goes here } test(”SubCut scalatest test 1") { ProjectConfiguration.modifyBindings { module => // new calls to bind inside here val service = new UserService("myUserService")(module) // all testcode using service also goes inside here } }

Slide 16

Slide 16 text

A  good  (Sub)Cut?  

Slide 17

Slide 17 text

What  now?  

Slide 18

Slide 18 text

Credits   •  “Dependency  Injec+on  Op+ons  in  Scala”  –  Dick   Wall  @  JavaZone  X  2011   – h?p://vimeo.com/28792660   •  h?ps://github.com/dickwall/subcut   •  h?ps://github.com/dickwall/subcut/blob/ master/Ge`ngStarted.md   •  h?p://stackoverflow.com/ques+ons/7029268/ use-­‐subcut-­‐scala-­‐di-­‐on-­‐android   •  h?ps://github.com/janwe/javaBin-­‐ScalaDI  

Slide 19

Slide 19 text

BEKK CONSULTING AS SKUR 39, VIPPETANGEN. P.O. BOX 134 SENTRUM, 0102 OSLO, NORWAY. WWW.BEKK.NO Jan  Fredrik  Wedén   Manager,  Trondheim   @jfweden