Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Import as an antipattern - Demystifying Dependency Injection in Python

Import as an antipattern - Demystifying Dependency Injection in Python

Dependency Injection in Python is commonly seen as over-engineering, but I think this is a myth. DI is simple and powerful and can yield great benefits to the overall quality of your code.

Dependency Injection (DI) is a technique quite common in other programming languages that has never quite fitted into the Python programmer's mindset. Usually disregarded as over-engineering and complex, most of its alleged flaws have little to do with the underlying concepts but more with implementation details of large scale frameworks that obscure its core principles.

In my experience DI is simple and powerful and can greatly improve our design making our code is easier to test, extend and maintain.

In this talk I will start with a brief standard example and challenge common idioms that introduce coupling and reduce maintainability and extensibility. I will then introduce concepts like interfaces, inversion of control and DI and apply them showcasing how the design and overall quality of the code improves.

Along the way I will demonstrate how recent additions to Python and its tooling can help when applying these techniques and also address the common misconception among Python developers suggesting large complex frameworks are required to apply DI.

I will then share some examples of Dependency Injection in well known libraries and some hands-on stories where I have benefited from it in my day-to-day work. And finally I will provide some guidelines on identifying situations where DI shines and where its application might be less obvious or should be delayed until further domain knowledge is introduced.

With this talk I hope to demystify the Dependency Injection in the Python ecosystem as well as introduce and clarify important design concepts for a beginner to intermediate audience.

Yeray Díaz Díaz

September 15, 2019
Tweet

Other Decks in Programming

Transcript

  1. import
    as an anti-pattern
    Demystifying Dependency
    Injection in Python
    Yeray Díaz PyCon UK

    September 2019
    @yera_ee

    View Slide

  2. ! I’m Yeray
    • Freelance Software Engineer based in
    London

    • Co-organizer of London Python
    Meetup

    • Moderator and contributor for PyPI

    View Slide

  3. Dependency

    Injection

    View Slide

  4. Dependency

    Injection
    Worst name ever?

    View Slide

  5. Dependency… Injection?
    Daniel Frank
    https://xkcd.com/327/

    View Slide

  6. What do programmers think?
    Daniel Frank
    https://twitter.com/yera_ee/status/1072540888264597506

    View Slide

  7. What do programmers think?
    Daniel Frank
    https://twitter.com/yera_ee/status/1072540888264597506

    View Slide

  8. How does DI
    make you feel?

    View Slide

  9. View Slide

  10. View Slide

  11. View Slide

  12. View Slide

  13. View Slide

  14. View Slide

  15. View Slide

  16. View Slide

  17. View Slide

  18. View Slide

  19. View Slide

  20. View Slide

  21. View Slide

  22. View Slide

  23. View Slide

  24. View Slide

  25. View Slide

  26. Coupling

    View Slide

  27. Where did it all go wrong?

    View Slide

  28. Where did it all go wrong?

    View Slide

  29. Where did it all go wrong?

    View Slide

  30. import is an
    anti-pattern

    View Slide

  31. View Slide

  32. View Slide

  33. “Depend on
    abstractions,
    not concretions”

    View Slide

  34. What is an abstraction?
    •A formal interface definition

    •A series of objects that implement
    that interface

    •Encapsulating the lower level details

    View Slide

  35. In our case

    View Slide

  36. In our case

    View Slide

  37. Or even better…

    View Slide

  38. And now…

    View Slide

  39. And now…

    View Slide

  40. And now…

    View Slide

  41. And now…

    View Slide

  42. And now…

    View Slide

  43. And now…
    Dependency
    Injection!

    View Slide

  44. Going concrete

    View Slide

  45. Going concrete

    View Slide

  46. FileProcessor
    Google Storage
    What just happened?

    View Slide

  47. FileProcessor
    GCSFileRepo
    FileRepoABC

    View Slide

  48. FileProcessor
    GCSFileRepo
    FileRepoABC

    View Slide

  49. FileProcessor
    GCSFileRepo
    FileRepoABC
    Inversion of
    Control

    View Slide

  50. What just happened?
    •FileProcessor now has one
    responsibility: compute the hash of
    file contents

    •It no longer instantiates the repo, this
    responsibility is moved to the caller

    View Slide

  51. Where do dependencies
    come from?
    • One place where all instances
    of all dependencies are created

    • The Composition Root
    • Usually at the entry point of
    our application

    View Slide

  52. Composition root

    View Slide

  53. Composition root

    View Slide

  54. Composition root

    View Slide

  55. Composition root

    View Slide

  56. Benefits of DI
    • Interception

    • Lifetime

    • Composition

    View Slide

  57. Interception

    View Slide

  58. Interception

    View Slide

  59. Interception
    Liskov
    Substitution
    Principle

    View Slide

  60. But of course…

    View Slide

  61. But of course…
    Boundary
    test

    View Slide

  62. Boundary tests
    •Isolated from changes in the business
    logic

    •We test that it implements the interface
    correctly

    •Will not change at all if the interface is
    stable

    •Possibility for integration tests

    View Slide

  63. Lifetime

    View Slide

  64. Lifetime

    View Slide

  65. Lifetime

    View Slide

  66. Composition

    View Slide

  67. Composition

    View Slide

  68. Composition

    View Slide

  69. Composition
    Open ̶Closed
    Principle

    View Slide

  70. Bonus principles
    • Dependency Inversion 

    Principle

    • Single Responsibility

    Principle

    • Interface Segregation

    Principle

    View Slide

  71. Bonus principles
    • Dependency Inversion 

    Principle

    • Single Responsibility

    Principle

    • Interface Segregation

    Principle

    View Slide

  72. Bonus principles
    • Dependency Inversion 

    Principle

    • Single Responsibility

    Principle

    • Interface Segregation

    Principle


    View Slide

  73. Bonus principles
    • Dependency Inversion 

    Principle

    • Single Responsibility

    Principle

    • Interface Segregation

    Principle



    View Slide

  74. Pure DI
    •DI Frameworks aim to simplify
    the composition

    •DI containers vs Pure DI

    •DI containers are NOT required

    View Slide

  75. Where does DI shine?

    View Slide

  76. Where does DI shine?
    •Where the abstraction is clear

    View Slide

  77. Where does DI shine?
    •Where the abstraction is clear
    •Runtime dependencies and
    boundaries

    View Slide

  78. Where does DI shine?
    •Where the abstraction is clear
    •Runtime dependencies and
    boundaries
    •Business logic abstractions may be
    harder to define and costly to
    backtrack

    View Slide

  79. Conclusions
    •Every import of an external library is
    creating coupling

    •Consider the responsibility that’s being
    fulfilled

    •Abstract only if it’s obvious

    •You do not need to go all-in with
    frameworks, DI can be applied gradually

    View Slide

  80. Further reading
    https://www.manning.com/books/dependency-injection-principles-practices-patterns

    View Slide

  81. Further reading
    https://www.sandimetz.com/99bottles

    View Slide

  82. Further reading
    https://www.destroyallsoftware.com/talks/boundaries

    View Slide

  83. Thank you!
    Yeray Díaz @yera_ee

    View Slide