Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
Revisit Dependency
Injection in Scala
Naoki Takezoe
@takezoen
at Airframe Meetup #3
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
What’s Dependency Injection?
● Inversion of Control
● Externalize components dependency and make it configurable
● Encourage clean components design
● Components can be replaced (e.g. for testing)
● Good collaboration with Aspect Oriented Programming
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
Dependency Injection in Java
Explicit configuration to Less configuration
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
Dependency Injection in Scala
● Java based DI container
○ Google Guice
● Pure Scala approach
○ Implicit parameter
○ Cake Pattern
○ Reader Monad, etc
● Scala native DI library
○ MacWire
○ Airframe
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
Google Guice
● Widely used in Scala because of Play Framework
● Easy to use and understand
● Lack of Scala specific functionality
Define binding in Module
Use @Inject annotation for DI
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
Implicit parameter
● No external library is required
● Easy to use and understand
● All necessary components must be in the same scope
Take necessary components as implicit parameter
Define necessary implicit val or def in the execution scope
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
Cake Pattern
● No external library is required
● Boilerplate
Combine by mix-in
Declare dependency as self-type annotation
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
Reader Monad
● Carry components around as an environment
● Need to put all necessary components together into the environment
Run with environment
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
MacWire
● Generate instance creation code with constructor injection by macro
● Rich features (e.g. multi binding, tagged binding, intercepter, etc)
● No boilerplate
● All necessary components must be in the same scope
Create instance using wire[T] macro
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
Airframe
● Constructor injection and In-trait injection
● Rich features (e.g. tagged binding, type alias binding, config binding, etc)
● Less configuration by automatic instance creation
● Life-cycle management
In-trait injection
Define binding on Design if you need to
override default binding
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
Runtime DI vs Compile-time DI
● Runtime DI
○ Google Guice
○ Airframe
● Compile-time ID
○ Pure Scala approaches
○ MacWire
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
Runtime DI vs Compile-time DI
Runtime DI Compile-time DI
Binding error Runtime error Compilation error
Configuration Less configuration Boilerplate is necessary
Life-cycle management Yes No
Overhead Runtime Compile-time
External library Required Not required / Required
Scala specific features Yes / No Yes
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.
What approach is the best?
● Do you need auto-wiring?
● Which do you need? compile-time dependency check or dynamic-type
binding?
● Do you need object life-cycle management?
Thank You!
Danke!
Merci!
谢谢!
ありがとう!
Gracias!
Kiitos!
Copyright 1995-2019 Arm Limited (or its affiliates). All rights reserved.

Revisit Dependency Injection in scala

  • 1.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. Revisit Dependency Injection in Scala Naoki Takezoe @takezoen at Airframe Meetup #3
  • 2.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. What’s Dependency Injection? ● Inversion of Control ● Externalize components dependency and make it configurable ● Encourage clean components design ● Components can be replaced (e.g. for testing) ● Good collaboration with Aspect Oriented Programming
  • 3.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. Dependency Injection in Java Explicit configuration to Less configuration
  • 4.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. Dependency Injection in Scala ● Java based DI container ○ Google Guice ● Pure Scala approach ○ Implicit parameter ○ Cake Pattern ○ Reader Monad, etc ● Scala native DI library ○ MacWire ○ Airframe
  • 5.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. Google Guice ● Widely used in Scala because of Play Framework ● Easy to use and understand ● Lack of Scala specific functionality Define binding in Module Use @Inject annotation for DI
  • 6.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. Implicit parameter ● No external library is required ● Easy to use and understand ● All necessary components must be in the same scope Take necessary components as implicit parameter Define necessary implicit val or def in the execution scope
  • 7.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. Cake Pattern ● No external library is required ● Boilerplate Combine by mix-in Declare dependency as self-type annotation
  • 8.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. Reader Monad ● Carry components around as an environment ● Need to put all necessary components together into the environment Run with environment
  • 9.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. MacWire ● Generate instance creation code with constructor injection by macro ● Rich features (e.g. multi binding, tagged binding, intercepter, etc) ● No boilerplate ● All necessary components must be in the same scope Create instance using wire[T] macro
  • 10.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. Airframe ● Constructor injection and In-trait injection ● Rich features (e.g. tagged binding, type alias binding, config binding, etc) ● Less configuration by automatic instance creation ● Life-cycle management In-trait injection Define binding on Design if you need to override default binding
  • 11.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. Runtime DI vs Compile-time DI ● Runtime DI ○ Google Guice ○ Airframe ● Compile-time ID ○ Pure Scala approaches ○ MacWire
  • 12.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. Runtime DI vs Compile-time DI Runtime DI Compile-time DI Binding error Runtime error Compilation error Configuration Less configuration Boilerplate is necessary Life-cycle management Yes No Overhead Runtime Compile-time External library Required Not required / Required Scala specific features Yes / No Yes
  • 13.
    Copyright 1995-2019 ArmLimited (or its affiliates). All rights reserved. What approach is the best? ● Do you need auto-wiring? ● Which do you need? compile-time dependency check or dynamic-type binding? ● Do you need object life-cycle management?
  • 14.