Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Slaying Sacred Cows:
Deconstructing
Dependency Injection
Tomer Gabel
Full Disclosure
• I was never a fan
• I tried researching
this properly…
– Read a ton of material
– Interviewed people
– S...
Semantics
When I say “dependency injection”, you’re
probably thinking of this:
public class BillingModule extends Abstract...
1. THE “D” IN SOLID
Image: Peter von Bagh, “Just Frozen Water” via Flickr (CC0 1.0 Public Domain)
Back to Basics
• Single responsibility
• Open/closed
• Liskov substitution principle
• Interface segregation
• Dependency ...
Back to Basics
• Single responsibility
• Open/closed
• Liskov substitution principle
• Interface segregation
• Dependency ...
Dependency Inversion
• A simple idea
• Given a dependency:
– A must not depend on B
directly
OAuthProvider
MysqlUserStore
...
Dependency Inversion
• A simple idea
• Given a dependency:
– A must not depend on B
directly
– Instead, A depends on
an ab...
The Verdict
• Dependency
inversion is old hat
– Seems obvious now
– First postulated by
Uncle Bob in 1994 (!)
• We’ve come...
2. DECOUPLE
ME SOFTLY
Image: Mark Menzies, “Le Chav Sportif” via Flickr (CC-BY-NC-SA 2.0)
Dependency Injection
• Let’s assume SOLID…
• Given a dependency:
– Who owns it?
– What is the lifecycle?
• Traditionally:
...
Dependency Injection
• DI stipulates:
– Services should not
build dependencies
– But instead receive them
– Dependencies a...
The Verdict
• Dependency
injection is good
• If taken at face value:
– No frameworks
– No containers
– No reflection
– Sim...
3. THINGS
GET HAIRY
Image: Matt Acevedo, “Alpaca” via Flickr (CC-BY 2.0)
Inversion of Control
• IoC is not a pattern
• It’s a design principle
• Traditionally:
– “Main” flow calls into
components...
Inversion of Control
• IoC is not a pattern
• It’s a design principle
• With IoC:
– Control is surrendered
to a container
...
Inversion of Control
• IoC means many things
– Servlet containers
– Plugin systems
– Stream computing
– “DI” containers
• ...
IoC & DI
• Consider Spring/Guice
– A runtime container
– Manages components
– … including lifecycle
– … and automatic wiri...
Perceived Benefits
• Why use a container?
– Simplify wiring
– Simplify testing
– Dynamic configuration
– Support for AOP
•...
Perceived Benefits
• Why use a container?
– Simplify wiring
– Simplify testing
– Dynamic configuration
– Support for AOP
•...
Simplified Wiring
class MyApp {
DBI db = new DBIFactory().build(...);
EventStore eventStore =
new MysqlEventStore(db);
Sna...
Simplified Wiring
class MyApp {
DBI db = new DBIFactory().build(...);
EventStore eventStore =
new MysqlEventStore(db);
Sna...
Simplified Wiring
class MyApp {
DBI db = new DBIFactory().build(...);
EventStore eventStore =
new MysqlEventStore(db);
Sna...
Simplified Wiring
• No tangible benefit!
– Wiring is trivial
• Real, tangible downsides
– Startup time
– Code navigability...
Simplify Testing
• Proponents will tell you:
1. Bring up a container
2. Swap out components
3. Bob’s your uncle
Simplify Testing
deconstruction (source: dictionary.com)
Noun
1. a technique of literary analysis that regards
meaning as ...
Simplify Testing
• Congratulations!
• You’re doing
deconstructive
testing
Wha-huh?
Constructive testing Deconstructive testing
MysqlEventStore
DataSource
SiteService
MysqlEventStore
DataSource
Mys...
Wha-huh?
Constructive testing Deconstructive testing
MysqlEventStore
DataSource
SiteService
MysqlEventStore
DataSource
Moc...
Simplify Testing
• This is a bad idea
– Hard to reason about
– Have to deal with
subtle interactions
– Does not reflect yo...
IN SUMMARY…
IoC is a solution in
search of a problem
… except …
• With huge codebases
– Read: “Monoliths”
– Read: “Enterprise”
• Enables a tradeoff
– Developer discipline
– Co...
… except …
• With huge codebases
– Read: “Monoliths”
– Read: “Enterprise”
• Enables a tradeoff
– Developer discipline
– Co...
QUESTIONS?
Thank you for listening
tomer@tomergabel.com
@tomerg
http://engineering.wix.com
Sample Project:
http://tinyurl....
Upcoming SlideShare
Loading in …5
×

Slaying Sacred Cows: Deconstructing Dependency Injection

807 views

Published on

This talk revisits dependency injection, and attempts to answer a single question honestly, or at least while pointing out and acknowledging the biases at play: "is dependency injection a good thing?"

Dependency injection has fast established itself as a major design pattern in modern software. No longer the province of server-side and enterprise software, it is now a fundamental component of frameworks from Spring to Angular.js.

With such widespread success, the time is ripe to take a fresh look at dependency injection if we are to understand it better. After all, DI is instrumental in building large systems that are loosely coupled, and it cleanly separates your tests from implementation... or does it?

(A talk given at GeeCON 2017 in Prague, Czech Republic)

Published in: Engineering
  • Be the first to comment

Slaying Sacred Cows: Deconstructing Dependency Injection

  1. 1. Slaying Sacred Cows: Deconstructing Dependency Injection Tomer Gabel
  2. 2. Full Disclosure • I was never a fan • I tried researching this properly… – Read a ton of material – Interviewed people – Sat and thought • Still turned out a rant Image: ImgFlip
  3. 3. Semantics When I say “dependency injection”, you’re probably thinking of this: public class BillingModule extends AbstractModule { @Override protected void configure() { bind(TransactionLog.class).to(DatabaseTransactionLog.class); bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class); } } So did I.
  4. 4. 1. THE “D” IN SOLID Image: Peter von Bagh, “Just Frozen Water” via Flickr (CC0 1.0 Public Domain)
  5. 5. Back to Basics • Single responsibility • Open/closed • Liskov substitution principle • Interface segregation • Dependency inversion Image: Michael Feathers via MozaicWorks
  6. 6. Back to Basics • Single responsibility • Open/closed • Liskov substitution principle • Interface segregation • Dependency inversion Image: Michael Feathers via MozaicWorks
  7. 7. Dependency Inversion • A simple idea • Given a dependency: – A must not depend on B directly OAuthProvider MysqlUserStore “A” “B”
  8. 8. Dependency Inversion • A simple idea • Given a dependency: – A must not depend on B directly – Instead, A depends on an abstraction of B – B depends on the same abstraction OAuthProvider MysqlUserStore UserStore class class interface “A” “B”
  9. 9. The Verdict • Dependency inversion is old hat – Seems obvious now – First postulated by Uncle Bob in 1994 (!) • We’ve come a long way since! “The philosophy of one century is the common sense of the next.” -- Henry Ward Beecher Image: Mathew Brady, “Henry Ward Beecher” via Library of Congress (Public Domain)
  10. 10. 2. DECOUPLE ME SOFTLY Image: Mark Menzies, “Le Chav Sportif” via Flickr (CC-BY-NC-SA 2.0)
  11. 11. Dependency Injection • Let’s assume SOLID… • Given a dependency: – Who owns it? – What is the lifecycle? • Traditionally: – The depending service manages everything class UserService { private UserStore store = new MysqlUserStore(Config.JDBC_URL); bool authenticate(String userToken) { UserContext user = store.lookup(userToken); return user != null ? user.isActive() : false; } }
  12. 12. Dependency Injection • DI stipulates: – Services should not build dependencies – But instead receive them – Dependencies are state • It does not stipulate how to implement this class UserService { private UserStore store; public UserService(UserStore store) { this.store = store; } bool authenticate(String userToken) { // ... } }
  13. 13. The Verdict • Dependency injection is good • If taken at face value: – No frameworks – No containers – No reflection – Simply common sense Image: Tomas Catelazo via Wikimedia Commons (CC-BY-SA 4.0)
  14. 14. 3. THINGS GET HAIRY Image: Matt Acevedo, “Alpaca” via Flickr (CC-BY 2.0)
  15. 15. Inversion of Control • IoC is not a pattern • It’s a design principle • Traditionally: – “Main” flow calls into components – Control flows back to the “main” flow Main (entry point) • Configuration • Bootstrapping Event loop • Dequeue • Dispatch Event handler • Act on event • Done
  16. 16. Inversion of Control • IoC is not a pattern • It’s a design principle • With IoC: – Control is surrendered to a container – Container calls into components Main (entry point) • Setup IoC container • Bootstrapping/wiring • Event loop Event handler • Act on event • Done
  17. 17. Inversion of Control • IoC means many things – Servlet containers – Plugin systems – Stream computing – “DI” containers • We’ll focus on the latter
  18. 18. IoC & DI • Consider Spring/Guice – A runtime container – Manages components – … including lifecycle – … and automatic wiring Image: ImgFlip
  19. 19. Perceived Benefits • Why use a container? – Simplify wiring – Simplify testing – Dynamic configuration – Support for AOP • Let’s consider each Image: ImgFlip
  20. 20. Perceived Benefits • Why use a container? – Simplify wiring – Simplify testing – Dynamic configuration – Support for AOP • Let’s consider each Image: ImgFlip
  21. 21. Simplified Wiring class MyApp { DBI db = new DBIFactory().build(...); EventStore eventStore = new MysqlEventStore(db); SnapshotStore snapshotStore = new MysqlSnapshotStore(db); Clock clock = Clock.systemUTC(); SiteService siteService = new DefaultSiteService( eventStore, snapshotStore, clock); }
  22. 22. Simplified Wiring class MyApp { DBI db = new DBIFactory().build(...); EventStore eventStore = new MysqlEventStore(db); SnapshotStore snapshotStore = new MysqlSnapshotStore(db); Clock clock = Clock.systemUTC(); SiteService siteService = new DefaultSiteService( eventStore, snapshotStore, clock); } class MyAppModule extends AbstractModule { @Override protected void configure() { bind(DBI.class).toProvider(...); bind(EventStore.class) .to(MysqlEventStore.class); bind(SnapshotStore.class) .to(MysqlSnapshotStore.class); bind(Clock.class) .toProvider(Clock::systemUTC); bind(SiteService.class) .to(DefaultSiteService.class); } }
  23. 23. Simplified Wiring class MyApp { DBI db = new DBIFactory().build(...); EventStore eventStore = new MysqlEventStore(db); SnapshotStore snapshotStore = new MysqlSnapshotStore(db); Clock clock = Clock.systemUTC(); SiteService siteService = new DefaultSiteService( eventStore, snapshotStore, clock); } class MyAppModule extends AbstractModule { @Override protected void configure() { bind(DBI.class).toProvider(...); bind(EventStore.class) .to(MysqlEventStore.class); bind(SnapshotStore.class) .to(MysqlSnapshotStore.class); bind(Clock.class) .toProvider(Clock::systemUTC); bind(SiteService.class) .to(DefaultSiteService.class); } }
  24. 24. Simplified Wiring • No tangible benefit! – Wiring is trivial • Real, tangible downsides – Startup time – Code navigability – Dynamic/reflective magic Image: André Nordstrand, “Loss of common sense” via Flickr (CC-BY-NC 2.0)
  25. 25. Simplify Testing • Proponents will tell you: 1. Bring up a container 2. Swap out components 3. Bob’s your uncle
  26. 26. Simplify Testing deconstruction (source: dictionary.com) Noun 1. a technique of literary analysis that regards meaning as resulting from the differences between words rather than their reference to the things they stand for.
  27. 27. Simplify Testing • Congratulations! • You’re doing deconstructive testing
  28. 28. Wha-huh? Constructive testing Deconstructive testing MysqlEventStore DataSource SiteService MysqlEventStore DataSource MysqlSnapshotStore DataSource Clock
  29. 29. Wha-huh? Constructive testing Deconstructive testing MysqlEventStore DataSource SiteService MysqlEventStore DataSource MockSnapshotStore Fixed Clock
  30. 30. Simplify Testing • This is a bad idea – Hard to reason about – Have to deal with subtle interactions – Does not reflect your unit structure • Most importantly… – Leads to poor design! Image: Viewminder, “Strange Bedfellows” via Flickr (CC-BY-NC-ND 2.0)
  31. 31. IN SUMMARY… IoC is a solution in search of a problem
  32. 32. … except … • With huge codebases – Read: “Monoliths” – Read: “Enterprise” • Enables a tradeoff – Developer discipline – Code coherence, simplicity, navigability
  33. 33. … except … • With huge codebases – Read: “Monoliths” – Read: “Enterprise” • Enables a tradeoff – Developer discipline – Code coherence, simplicity, navigability Corollary: If you’re seeing benefit from IoC, your codebase is already out of control.
  34. 34. QUESTIONS? Thank you for listening tomer@tomergabel.com @tomerg http://engineering.wix.com Sample Project: http://tinyurl.com/event-sourcing-sample This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

×