3 Revitalized dependency injection

 

This chapter covers

  • How the dependency injection mechanism works under the hood
  • Injection contexts
  • Using the inject function instead of constructor-based dependency injection and the benefits of this approach
  • Using the inject function to convert class-based guards/resolvers/interceptors to functional ones

Dependency injection (DI) is famously the most loved and stable feature that Angular provides as a framework. DI is used extensively in every single Angular project, and it is hard to imagine a flexible and maintainable codebase without its advantages. So what changed, and importantly, why, if it was already so stable? This question will be our subject of exploration in this chapter, which, funny enough, actually revolves around one single function, inject (actually not even a new function!), which, almost accidentally, made a minor revolution in Angular projects all over the community.

3.1 How does dependency injection work?

Let’s start our exploration by diving into the DI mechanism to understand how it works and how we can utilize it to build more flexible codebases. But first, let’s briefly discuss what, in general, DI is and what it is not.

3.1.1 Why do we need DI?

3.1.2 Let’s build a primitive DI mechanism

3.1.3 Dependency injection the Angular way

3.1.4 Injection contexts

3.2 The inject function

3.2.1 Another way of injecting dependencies

3.2.2 Injecting dependencies outside classes

3.2.3 Why we should always use inject

3.2.4 What about the drawbacks?

3.3 Functional guards, resolvers, and interceptors

3.3.1 Building an AuthGuard

3.3.2 Building an EmployeeResolver

3.3.3 Adding tokens to HTTP requests

3.3.4 Migrating to functional guards/resolvers/interceptors

3.4 DI deep dive

3.4.1 DI lookup and how to modify it

3.4.2 Truncating text with DI

3.5 Exercises for the reader