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 full-size slide

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

    • Co-organizer of London Python
    Meetup

    • Moderator and contributor for PyPI

    View full-size slide

  3. Dependency

    Injection

    View full-size slide

  4. Dependency

    Injection
    Worst name ever?

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  8. How does DI
    make you feel?

    View full-size slide

  9. Where did it all go wrong?

    View full-size slide

  10. Where did it all go wrong?

    View full-size slide

  11. Where did it all go wrong?

    View full-size slide

  12. import is an
    anti-pattern

    View full-size slide

  13. “Depend on
    abstractions,
    not concretions”

    View full-size slide

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

    •A series of objects that implement
    that interface

    •Encapsulating the lower level details

    View full-size slide

  15. Or even better…

    View full-size slide

  16. And now…
    Dependency
    Injection!

    View full-size slide

  17. Going concrete

    View full-size slide

  18. Going concrete

    View full-size slide

  19. FileProcessor
    Google Storage
    What just happened?

    View full-size slide

  20. FileProcessor
    GCSFileRepo
    FileRepoABC

    View full-size slide

  21. FileProcessor
    GCSFileRepo
    FileRepoABC

    View full-size slide

  22. FileProcessor
    GCSFileRepo
    FileRepoABC
    Inversion of
    Control

    View full-size slide

  23. 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 full-size slide

  24. 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 full-size slide

  25. Composition root

    View full-size slide

  26. Composition root

    View full-size slide

  27. Composition root

    View full-size slide

  28. Composition root

    View full-size slide

  29. Benefits of DI
    • Interception

    • Lifetime

    • Composition

    View full-size slide

  30. Interception

    View full-size slide

  31. Interception

    View full-size slide

  32. Interception
    Liskov
    Substitution
    Principle

    View full-size slide

  33. But of course…

    View full-size slide

  34. But of course…
    Boundary
    test

    View full-size slide

  35. 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 full-size slide

  36. Composition
    Open ̶Closed
    Principle

    View full-size slide

  37. Bonus principles
    • Dependency Inversion 

    Principle

    • Single Responsibility

    Principle

    • Interface Segregation

    Principle

    View full-size slide

  38. Bonus principles
    • Dependency Inversion 

    Principle

    • Single Responsibility

    Principle

    • Interface Segregation

    Principle

    View full-size slide

  39. Bonus principles
    • Dependency Inversion 

    Principle

    • Single Responsibility

    Principle

    • Interface Segregation

    Principle


    View full-size slide

  40. Bonus principles
    • Dependency Inversion 

    Principle

    • Single Responsibility

    Principle

    • Interface Segregation

    Principle



    View full-size slide

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

    •DI containers vs Pure DI

    •DI containers are NOT required

    View full-size slide

  42. Where does DI shine?

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  45. 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 full-size slide

  46. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  50. Thank you!
    Yeray Díaz @yera_ee

    View full-size slide