Skip to content

docs: update di guide (part 1) #62127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

bencodezen
Copy link
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.dev application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

The current dependency injection guide is fragmented and disconnected.

What is the new behavior?

This PR introduces the first iteration of changes to make the DI guide cohesive and up to date.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@bencodezen bencodezen requested review from jelbourn and JeanMeche June 18, 2025 18:56
@angular-robot angular-robot bot added the area: docs Related to the documentation label Jun 18, 2025
@ngbot ngbot bot added this to the Backlog milestone Jun 18, 2025
@bencodezen bencodezen added the action: review The PR is still awaiting reviews from at least one requested reviewer label Jun 18, 2025
@bencodezen bencodezen requested a review from alxhub June 18, 2025 19:00
@jelbourn jelbourn added adev: preview target: patch This PR is targeted for the next patch release labels Jun 18, 2025
Copy link

github-actions bot commented Jun 18, 2025

Deployed adev-preview for cd2ea8a to: https://ng-dev-previews-fw--pr-angular-angular-62127-adev-prev-wy6p8srf.web.app

Note: As new commits are pushed to this pull request, this link is updated after the preview is rebuilt.

@bencodezen bencodezen force-pushed the docs/di-guide-pt-1 branch from 7d3da32 to 399bd4d Compare June 19, 2025 16:05
docs: use more accurate word choice

Co-authored-by: Matthieu Riegler <[email protected]>

docs: use better file name for example

Co-authored-by: Enea Jahollari <[email protected]>

docs: update dedicated di guide with more accurate statements

docs: apply suggestions from code review

Co-authored-by: Jeremy Elbourn <[email protected]>

docs: iterate on new structure for di part 1 guide
@bencodezen bencodezen force-pushed the docs/di-guide-pt-1 branch from 379ec07 to cd2ea8a Compare June 24, 2025 15:37
@bencodezen bencodezen requested a review from jelbourn June 24, 2025 15:37
@@ -1,29 +1,142 @@
<docs-decorative-header title="Dependency injection in Angular" imgSrc="adev/src/assets/images/dependency_injection.svg"> <!-- markdownlint-disable-line -->
"DI" is a design pattern and mechanism for creating and delivering some parts of an app to other parts of an app that require them.

[Dependency Injection (DI)](https://en.wikipedia.org/wiki/Dependency_injection) is a design pattern used to organize and share code across an application.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[Dependency Injection (DI)](https://en.wikipedia.org/wiki/Dependency_injection) is a design pattern used to organize and share code across an application.
Dependency Injection is a design pattern used to organize and share code across an application.

I noticed in the preview that markdown links don't work inside <docs-decorative-header>, so I think the link to wikipedia needs to go in the paragraph below (were I think we can also introduce the "DI" initialism)

Hierarchical DI enables you to share dependencies between different parts of the application only when and if you need to. This is an advanced topic.
</docs-card>
</docs-card-container>
As an application grows, developers often need to reuse and share features across different parts of the codebase. Dependency Injection (DI) is a design pattern used to organize and share code across an application by allowing you to "inject" features into different parts.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
As an application grows, developers often need to reuse and share features across different parts of the codebase. Dependency Injection (DI) is a design pattern used to organize and share code across an application by allowing you to "inject" features into different parts.
As an application grows, developers often need to reuse and share features across different parts of the codebase. [Dependency Injection (DI)]((https://en.wikipedia.org/wiki/Dependency_injection) is a design pattern used to organize and share code across an application by allowing you to "inject" features into different parts.

- **Scalability**: Modular functionality can be reused across multiple contexts and allows for easier scaling.
- **Better testing**: DI allows unit tests to easily use [test doubles](https://en.wikipedia.org/wiki/Test_double) for situations when using a real implementation is not practical.

## How does dependency injection (DI) work in Angular?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## How does dependency injection (DI) work in Angular?
## How does dependency injection work in Angular?

opinion: I think it's fine to introduce "DI" above once, and then use in it paragraph text throughout (while still using the full "dependency injection" in titles)

- Code can _provide_, or makes available, values.
- Code can _inject_, or ask for, those values as dependencies.

"Values," in this context, can be any JavaScript value, including objects and functions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Values," in this context, can be any JavaScript value, including objects and functions.
"Values," in this context, can be any JavaScript value, including objects and functions. Common types of injected dependencies include:
- **Configuration values**: Environment-specific constants, API URLs, feature flags, etc.
- **Factories**: Functions that create objects or values based on runtime conditions
- **Services**: Classes that provide common functionality, business logic, or state

What do you think about folding the "What are dependencies?" section below here? I think this captures the same idea, helps with the transition to services, and lets the guide move from services to infecting stuff for directly


## Injecting dependencies with `inject()`

You can inject dependencies using Angular's helper function, `inject()`. It interfaces directly with Angular's dependency injection (DI) system to request a dependency.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can inject dependencies using Angular's helper function, `inject()`. It interfaces directly with Angular's dependency injection (DI) system to request a dependency.
You can inject dependencies using Angular's `inject()` function.
  • I personally don't love "helper" as a term, since IMO it doesn't carry much meaning by itself. I think it also implies a certain unimportance / auxiliary-ness, where inject is more core to the framework
  • I'm not sure what the second sentence is is trying to get across- is it necessary? Or is there a point we'd still want to convey here?

@@ -0,0 +1,362 @@
# Providing other dependencies

When [creating and using services](guide/di/creating-and-using-services), you typically import the class you want to provide as a service and include it directly in the array.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just repeating a comment from the other guide here, but most of the time you wouldn't add anything to the providers array, and would just consume things that are providedIn: 'root'.

That does lead me to thinking that we should have some guidance on when it does make sense to use component/directive providers and when it makes sense to add things to the top-level providers in bootstrapApplication


There are two primary parts to every provider configuration object:

1. **Provider token**: The unique ID that Angular uses to fetch the dependency and is configured via the provide key.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. **Provider token**: The unique ID that Angular uses to fetch the dependency and is configured via the provide key.
1. **Provider token**: The unique key that Angular uses to get the dependency and is set via the `provide` property.

We generally use the term "key" rather than "ID" (like with a hash map)

There are two primary parts to every provider configuration object:

1. **Provider token**: The unique ID that Angular uses to fetch the dependency and is configured via the provide key.
2. **Value**: The actual dependency that you want Angular to fetch. This is configured with a different key (i.e., useClass, useValue, etc.) based on the desired type of dependency. We will cover this more in-depth on in the guide.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2. **Value**: The actual dependency that you want Angular to fetch. This is configured with a different key (i.e., useClass, useValue, etc.) based on the desired type of dependency. We will cover this more in-depth on in the guide.
2. **Value**: The actual dependency that you want Angular to fetch. This is configured with a different key (i.e., useClass, useValue, etc.) based on the desired type of dependency. The following section covers these options in more detail.

nit: avoid first person, use present tense


Let's dive deeper into what's going on behind the scenes.

## Understanding the provider configuration object
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to draw an analogy to a hash map in this section? (key + value)


#### Injection tokens

Angular provides a built-in [`InjectionToken`](api/core/InjectionToken) class that generates a unique ID for its dependency injection system.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Angular provides a built-in InjectionToken class that generates a unique ID for its dependency injection system.

This makes it sound like Angular generates a string ID, but really Angular just uses object reference equality (===) to getting the injected value.

(we shouldn't say this here, but InjectationToken isn't even strictly necessary; anything can be a key, and Angular just compares based on ===. The string ID you give to the token is mainly for debugging purposes, since the symbol itself may be minified/obfuscated in production mode).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
action: review The PR is still awaiting reviews from at least one requested reviewer adev: preview area: docs Related to the documentation target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants