Dependency Injection, but why?

September 16th, 2020  by  Matthew Gray

Dependency Injection

  • The “D” in S.O.L.I.D. (Dependency Inversion)
  • A form of Inversion of Control (more on this later)
  • Helps with having to support multiple configurations (based on env)
  • Makes testing dependency-laced code easier
  • Most popular pattern is constructor injection, however, can be set explicitly as a public property of an object, or as an method argument

Inversion of Control

  • A set of scary words that I can best describe as “loose coupling” and “reusability”, maybe even delegation
  • Includes dependency injection (arguably the most popular type of Inversion of Control)
  • Service locator pattern 🗺
  • Template method pattern

But, why?

  • Decouples the creation, configuration and usage of a dependency
  • You can change the dependency without needing to change the object that depends on it (caveat: they need to share the same interface)
  • Promotes well defined interfaces and reusable code ♻
  • More flexibility with configuration of an application (using a no-op dependency object in test or development)
  • Simplified testing 🙃
  • NestJS leans heavily on DI

How do we do it?

Interfaces are key

  • Consistent implementations of the dependency
  • Type checked languages really shine ✨
  • Can also be done with weak types, but more challenging since no type-checking (think duck-typing 🦆, base class inheritance)

Constructors

  • 💉 Inject the dependency in the object’s constructor
  • Can also be injected via a builder pattern
  • Allows for dependencies to remain in the private interface of the dependent object

Testing made easy

  • Implement null object pattern for easy testing
  • No need for dependencies to be configured any deeper than the first level
  • Can still spy on methods 👁
  • Great for unit tests, no real improvement for integration testing

Dependency Injection in NestJS

  • Configured through modules via imports, providers, and exports
  • Actual injection handled by decorators inside constructors
  • Dependencies are built once, and then held in memory with a unique identifier and fetched for injection
  • Can look overwhelming at first glance
  • Think of it as mixing DI and the Service Locator Pattern

But what about Ruby, and Rails?

  • Dependency Injection can be performed anywhere you can write code 👩‍💻
  • It does happen in Rails core libraries
  • Mainly used in configuration

But what about React?

  • You are already using dependency injection
  • JSX calls the render function
  • Inject callbacks/methods into a component as props
  • Can adopt pattern in service classes, because you can use DI wherever you can write code 🤔
Share

Evernorth, the health services segment of Cigna Corporation, selects Hinge Health for Digital Health Formulary. Read Press Release