-
Notifications
You must be signed in to change notification settings - Fork 26.4k
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
base: main
Are you sure you want to change the base?
Conversation
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. |
7d3da32
to
399bd4d
Compare
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
379ec07
to
cd2ea8a
Compare
@@ -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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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).
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
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?
Other information