liveBook · Manning

Dependency injection

As explained in Infrastructure as Code, Patterns and Practices: With examples in Python and Terraform

Dependency injection is a design pattern in which high-level modules obtain low-level dependencies through an abstraction rather than constructing or directly binding to them.

Dependency injection decouples high-level infrastructure resources from low-level dependencies. High-level resources request low-level attributes through an abstraction instead of constructing or binding directly to them. The pattern combines inversion of control with dependency inversion, allowing network changes to evolve without disrupting servers, queues, applications, or databases. section 4.2 section 4.2.3

Apply dependency injection through these infrastructure practices:

  • Use an infrastructure API or state as an abstraction layer; the high-level resource retrieves and parses the metadata it needs. section 4.2.3
  • Start with a facade when one low-level module serves a few high-level modules; use an adapter for many consumers or heterogeneous providers, and a mediator for many interdependent resources. section 4.6
  • Preserve idempotency, composability, and evolvability while isolating changes between modules and resources. section 4.6

Server and network

A server uses Apache Libcloud to query the GCP API for a subnet name, parse the returned metadata, and assign itself the fifth IP address in the network range. After the network range changes, the network is deployed first; the server retrieves the new metadata and recalculates its address without changing its own configuration logic. section 4.2.3

Infrastructure facades and mediators

A storage-bucket module outputs bucket attributes for an access-control module, exposing a simplified interface while keeping the bucket implementation independent. When a firewall depends on both a server and a network, a mediator creates the network first, the server second, and the firewall third; it can also organize deletion. section 4.3 section 4.5

Dependency injection also supports refactoring monolithic IaC. Extract independent resources first, separate their configuration and state, then update dependent resources to retrieve low-level identifiers through the provider API. Test each isolated component and repeat the workflow toward lower-level resources, minimizing disruption and preserving resource state. section 10.2.3 section 10.3

Figure 4.6 Dependency injection combines inversion of control and dependency inversion to loosen infrastructure dependencies and isolate low-level and high-level resources.

Use the dependency diagram to see how inversion of control and dependency inversion form an abstraction buffer between high- and low-level infrastructure resources. section 4.2.3

How Infrastructure as Code, Patterns and Practices: With examples in Python and Terraform covers it

How deep it goes
Explains principles, provider APIs, Python implementations, pattern selection, and refactoring steps through infrastructure examples.
Examples
Uses GCP servers, networks, subnets, storage buckets, access controls, firewalls, and monolithic IaC refactoring.
What it assumes
Assumes familiarity with infrastructure resources and IaC, while defining inversion of control and dependency inversion before combining them.
What you can do after
Apply it via Apache Libcloud or provider APIs to isolate infrastructure changes and organize dependent resource creation.
How it connects
Connects inversion of control, dependency inversion, facade, adapter, mediator, idempotency, composability, and evolvability.

Also explained in

Compare how 21 books explain dependency injection →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Infrastructure as Code, Patterns and Practices: With examples in Python and Terraform. The section links point to the parts of the book it draws on.