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

Myths and Truths about Dependency Injection

Avatar for Igor Igor
December 07, 2018

Myths and Truths about Dependency Injection

It’s 2018 and DI is a well-known and established technique on all major platforms and languages. So why can’t we still have a clear answer to the questions like ‘is DI/IoC container a mandatory thing to apply DI?’ or ‘what is a true way to implement DI in language/platform X?’ or ‘is it even a good/useful thing?’. Let’s find those answers together and refresh our memory on the initial goals and targets of DI and its surrounding design patterns.

Avatar for Igor

Igor

December 07, 2018
Tweet

More Decks by Igor

Other Decks in Technology

Transcript

  1. Myths and Truths about DI Or do we need a

    DI Container? By Igor Kochetov (@k04a), SDET at Unity Technologies
  2. @k04a Why we even talk about DI in 2018? There

    are conflicting opinions on the subject of DI Is it even still relevant? 2
  3. @k04a Nice one, but there are still questions... Who’s “we”

    who make sure you have what you need? How do we state “the need” in the code? Why one would use it? What are the benefits, actually? 4
  4. Known benefits Dependency Injection ❏ Reducing dependencies of components (and

    implementation details of those dependencies) ❏ Reusable code / swapping of components ❏ More testable code ❏ More readable code (by defining dependencies clearly) Loose coupling Isolated components are easier to: ❏ Modify, reuse or compose differently ❏ Test ❏ Reason about 5
  5. @k04a It is about Dependencies... Identifying dependencies in our code

    (and types of dependencies) Managing dependencies 6
  6. @k04a Programming to interfaces and D in SOLID High-level modules

    should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions. 7
  7. @k04a Also related: who owns the abstractions? Model abstractions around

    domain-specific scenarios instead of low-level implementation details “Adapt” external dependencies to match your domain concepts Hexagonal architecture or “Ports & Adapters”: 8
  8. @k04a Programming to interfaces and D in SOLID ServiceX is

    still tightly coupled to ServiceY! 9
  9. @k04a Resolve dependencies using Service Locator At first, looks like

    very good idea, which makes it even more dangerous. But now we introduce new dependency (on the container) We also hide actual dependencies How would you write tests for it? 11
  10. @k04a Constructor Injection is the way to go ❏ Explicitly

    lists dependencies ❏ Gives clues about what class might do ❏ Also an indicator of possible SRP violations 12
  11. Who’s “we” who make sure you have what you need?

    Or “Mommy and Daddy providing a drink” 14
  12. @k04a Many platforms provide out-of-the box DI capabilities .NET MVC

    / .NET Core MVC Spring in Java Angular JS Kind of making it a de-facto standard 15
  13. Myth: DI is a software library or a framework Or

    at least requires one to be done properly @k04a 16
  14. @k04a IoC Container or DI Container Container - software library

    that ‘resolves dependencies’ and manages their ‘lifetime’ ❏ Simplifies wiring and reduces maintenance ❏ Simplifies testing ❏ Allows for dynamic configuration ❏ Supports AOP But… Is it? 17
  15. @k04a Composition Root and Pure DI Creating all the stuff

    ‘normally’ in Composition Root (console app example) 19
  16. @k04a Is it OK to have all the components in

    the app root? It is good idea to keep individual components separated Until we have to actually assemble working application 20
  17. @k04a Explicit is better than implicit (Zen of Python) Cost

    of writing vs cost of reading (or imagine bringing a new member of the team into the codebase) Let IDE and code analysis tools be your friends It is actually IMPORTANT to know, what your app does (well-structured Composition Root serves as documentation providing bird-eye view on high-level features and use-cases) 21
  18. @k04a Composing within framework (.Net Core MVC) As easy as

    registering a custom IControllerActivator 22
  19. @k04a Use-case for Aspect-Oriented-Programming Applying cross-cutting concerns (also known as

    non-functional requirements) like: ❏ Logging ❏ Caching ❏ Security 24
  20. @k04a The power of Decorators (or AOP done right) Wrap

    logging around any actual implementation using Decorator design pattern 25
  21. @k04a Applying SOLID to extreme pushes you toward FP A

    lot of single-method interfaces and small focused classes (implementations) Which is good, until you have to write Decorators for every of them 27
  22. @k04a Decorator over generic ICommandHandler Now every ‘aspect’ becomes single

    Decorator over generic ICommandHandler <TCommand> interface 29
  23. @k04a Conclusions & takeaways Container is a dependency itself It

    also might be a sign your codebase grew too big (read “monolith”) DI ≠ Container DI is useful as a design pattern and allows greater flexibility and more manageable codebase (easier to test, modify and reason about) 31
  24. @k04a The big idea (or what those have in common?)

    ❏ Dependency Injection (DI) ❏ Continuous Integration (CI) / Continuous Deployment (CD) ❏ Scrum, Lean or any Agile methodology / framework of your choice ❏ DevOps Answer: Those were meant to be PRACTICES (not Tools) 32
  25. Join my professional network C# .NET & Python developer Interested

    in FP and ML Religious about good code, software design, TDD, SOLID QA and SDET at Unity Technologies Twitter: @k04a Linkedin: Igor Kochetov 33