Skip to content

Conversation

@alxhub
Copy link
Member

@alxhub alxhub commented Jun 30, 2022

This commit introduces a new API on EnvironmentInjector to run a function
in the context of the injector. This makes inject() available within the
body of the function to inject dependencies. We expect this functionality to
be very useful for designing ergonomic APIs both in and out of Angular, as
it should allow for a smaller and more functional API style.

Note that it's possible to implement nearly identical functionality in user
code already today:

function runInContext<T>(injector: EnvironmentInjector, fn: () => T): T {
 const token = new InjectionToken<T>('TOKEN');
 const tmpInjector = createEnvironmentInjector([
   {provide: token, useFactory: () => fn()},
 ], injector);

 return tmpInjector.get(token);
}

The factory provider for token in this example runs in the context of the
tmpInjector, giving it access to inject that can retrieve values from
injector as well. This is nearly identical, although because of the child
injector self and skipSelf injection options don't function correctly.

@alxhub alxhub added area: core Issues related to the framework runtime core: di target: minor This PR is targeted for the next minor release labels Jun 30, 2022
@ngbot ngbot bot modified the milestone: Backlog Jun 30, 2022
@alxhub alxhub force-pushed the env-injector-run branch from b5be982 to ddc339c Compare June 30, 2022 21:55
Copy link
Contributor

@atscott atscott left a comment

Choose a reason for hiding this comment

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

💯

Copy link
Contributor

@jessicajaniuk jessicajaniuk left a comment

Choose a reason for hiding this comment

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

Looks great! LGTM

reviewed-for: fw-core, public-api

@pullapprove pullapprove bot requested a review from dylhunn June 30, 2022 22:03
Copy link
Contributor

@atscott atscott left a comment

Choose a reason for hiding this comment

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

reviewed-for: public-api

Copy link
Contributor

@AndrewKushnir AndrewKushnir left a comment

Choose a reason for hiding this comment

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

👍

Reviewed-for: public-api

Copy link
Contributor

Choose a reason for hiding this comment

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

The get method can take advantage of the runInContext function now (to reuse the code) :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Hahaha :) I don't think we want the additional stack frame, but that'd be clever.

This commit introduces a new API on `EnvironmentInjector` to run a function
in the context of the injector. This makes `inject()` available within the
body of the function to inject dependencies. We expect this functionality to
be very useful for designing ergonomic APIs both in and out of Angular, as
it should allow for a smaller and more functional API style.

Note that it's possible to implement nearly identical functionality in user
code already today:

```typescript
function runInContext<T>(injector: EnvironmentInjector, fn: () => T): T {
  const token = new InjectionToken<T>('TOKEN');
  const tmpInjector = createEnvironmentInjector([
    {provide: token, useFactory: () => fn()},
  ], injector);

  return tmpInjector.get(token);
}
```

The factory provider for `token` in this example runs in the context of the
`tmpInjector`, giving it access to `inject` that can retrieve values from
`injector` as well. This is nearly identical, although because of the child
injector `self` and `skipSelf` injection options don't function correctly.
@alxhub alxhub force-pushed the env-injector-run branch from ddc339c to d8c336a Compare June 30, 2022 22:54
@alxhub alxhub added the action: merge The PR is ready for merge by the caretaker label Jun 30, 2022
* @param fn the closure to be run in the context of this injector
* @returns the return value of the function, if any
*/
abstract runInContext<ReturnT>(fn: () => ReturnT): ReturnT;
Copy link
Contributor

@alfaproject alfaproject Jul 1, 2022

Choose a reason for hiding this comment

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

Not that it matters but only T or T as a prefix like TReturn/TRet/TRes is more canonical

Copy link
Member

@pkozlowski-opensource pkozlowski-opensource left a comment

Choose a reason for hiding this comment

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

Yay! This is great and basically makes it possible to run a function in the DI context without registering anything in the DI container. Something we've been discussing a lot!

Awesome move @alxhub !

@pkozlowski-opensource pkozlowski-opensource removed the request for review from dylhunn July 1, 2022 11:27
@atscott
Copy link
Contributor

atscott commented Jul 1, 2022

This PR was merged into the repository by commit a7a14df.

@atscott atscott closed this in a7a14df Jul 1, 2022
crapStone pushed a commit to Calciumdibromid/CaBr2 that referenced this pull request Jul 24, 2022
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@angular/animations](https://github.com/angular/angular) | dependencies | minor | [`14.0.6` -> `14.1.0`](https://renovatebot.com/diffs/npm/@angular%2fanimations/14.0.6/14.1.0) |
| [@angular/common](https://github.com/angular/angular) | dependencies | minor | [`14.0.6` -> `14.1.0`](https://renovatebot.com/diffs/npm/@angular%2fcommon/14.0.6/14.1.0) |
| [@angular/compiler](https://github.com/angular/angular) | dependencies | minor | [`14.0.6` -> `14.1.0`](https://renovatebot.com/diffs/npm/@angular%2fcompiler/14.0.6/14.1.0) |
| [@angular/compiler-cli](https://github.com/angular/angular) | devDependencies | minor | [`14.0.6` -> `14.1.0`](https://renovatebot.com/diffs/npm/@angular%2fcompiler-cli/14.0.6/14.1.0) |
| [@angular/core](https://github.com/angular/angular) | dependencies | minor | [`14.0.6` -> `14.1.0`](https://renovatebot.com/diffs/npm/@angular%2fcore/14.0.6/14.1.0) |
| [@angular/forms](https://github.com/angular/angular) | dependencies | minor | [`14.0.6` -> `14.1.0`](https://renovatebot.com/diffs/npm/@angular%2fforms/14.0.6/14.1.0) |
| [@angular/platform-browser](https://github.com/angular/angular) | dependencies | minor | [`14.0.6` -> `14.1.0`](https://renovatebot.com/diffs/npm/@angular%2fplatform-browser/14.0.6/14.1.0) |
| [@angular/platform-browser-dynamic](https://github.com/angular/angular) | dependencies | minor | [`14.0.6` -> `14.1.0`](https://renovatebot.com/diffs/npm/@angular%2fplatform-browser-dynamic/14.0.6/14.1.0) |

---

### Release Notes

<details>
<summary>angular/angular</summary>

### [`v14.1.0`](https://github.com/angular/angular/blob/HEAD/CHANGELOG.md#&#8203;1410-2022-07-20)

[Compare Source](angular/angular@14.0.7...14.1.0)

#### Deprecations

##### core

-   The `createNgModuleRef` is deprecated in favor of newly added `createNgModule` one.
-   The bit field signature of `inject()` has been deprecated, in favor of the
    new options object. Correspondingly, `InjectFlags` is deprecated as well.

##### animations

| Commit | Type | Description |
| -- | -- | -- |
| [55308f2df5](angular/angular@55308f2) | feat | add `provideAnimations()` and `provideNoopAnimations()` functions ([#&#8203;46793](angular/angular#46793)) |

##### common

| Commit | Type | Description |
| -- | -- | -- |
| [4a2e7335b1](angular/angular@4a2e733) | feat | make the `CommonModule` pipes standalone ([#&#8203;46401](angular/angular#46401)) |
| [a7597dd080](angular/angular@a7597dd) | feat | make the CommonModule directives standalone ([#&#8203;46469](angular/angular#46469)) |

##### compiler

| Commit | Type | Description |
| -- | -- | -- |
| [33ce3883a5](angular/angular@33ce388) | feat | Add extended diagnostic to warn when missing let on ngForOf ([#&#8203;46683](angular/angular#46683)) |
| [6f11a58040](angular/angular@6f11a58) | feat | Add extended diagnostic to warn when text attributes are intended to be bindings ([#&#8203;46161](angular/angular#46161)) |
| [9e836c232f](angular/angular@9e836c2) | feat | warn when style suffixes are used with attribute bindings ([#&#8203;46651](angular/angular#46651)) |

##### compiler-cli

| Commit | Type | Description |
| -- | -- | -- |
| [93c65e7b14](angular/angular@93c65e7) | feat | add extended diagnostic for non-nullable optional chains ([#&#8203;46686](angular/angular#46686)) |
| [131d029da1](angular/angular@131d029) | feat | detect missing control flow directive imports in standalone components ([#&#8203;46146](angular/angular#46146)) |
| [6b8e60c06a](angular/angular@6b8e60c) | fix | improve the missingControlFlowDirective message ([#&#8203;46846](angular/angular#46846)) |

##### core

| Commit | Type | Description |
| -- | -- | -- |
| [e8e8e5f171](angular/angular@e8e8e5f) | feat | add `createComponent` function |
| [b5153814af](angular/angular@b515381) | feat | add `reflectComponentType` function |
| [96c6139c9a](angular/angular@96c6139) | feat | add ability to set inputs on ComponentRef ([#&#8203;46641](angular/angular#46641)) |
| [a6d5fe202c](angular/angular@a6d5fe2) | feat | alias `createNgModuleRef` as `createNgModule` ([#&#8203;46789](angular/angular#46789)) |
| [71e606d3c3](angular/angular@71e606d) | feat | expose EnvironmentInjector on ApplicationRef ([#&#8203;46665](angular/angular#46665)) |
| [19e6d9ccd3](angular/angular@19e6d9c) | feat | import AsyncStackTaggingZone if available ([#&#8203;46693](angular/angular#46693)) |
| [a7a14df5f8](angular/angular@a7a14df) | feat | introduce `EnvironmentInjector.runInContext` API ([#&#8203;46653](angular/angular#46653)) |
| [fa52b6e906](angular/angular@fa52b6e) | feat | options object to supersede bit flags for `inject()` ([#&#8203;46649](angular/angular#46649)) |
| [af20112222](angular/angular@af20112) | feat | support the descendants option for ContentChild queries ([#&#8203;46638](angular/angular#46638)) |
| [945a3ad359](angular/angular@945a3ad) | fix | Fix `runInContext` for `NgModuleRef` injector ([#&#8203;46877](angular/angular#46877)) |
| [bb7c80477b](angular/angular@bb7c804) | fix | make parent injector argument required in `createEnvironmentInjector` ([#&#8203;46397](angular/angular#46397)) |

##### http

| Commit | Type | Description |
| -- | -- | -- |
| [82acbf919b](angular/angular@82acbf9) | feat | improve error message for nullish header ([#&#8203;46059](angular/angular#46059)) |

##### router

| Commit | Type | Description |
| -- | -- | -- |
| [53ca936366](angular/angular@53ca936) | feat | Add ability to create `UrlTree` from any `ActivatedRouteSnapshot` ([#&#8203;45877](angular/angular#45877)) |
| [de058bba99](angular/angular@de058bb) | feat | Add CanMatch guard to control whether a Route should match ([#&#8203;46021](angular/angular#46021)) |
| [6c1357dd7d](angular/angular@6c1357d) | feat | Add stable cancelation code to `NavigationCancel` event ([#&#8203;46675](angular/angular#46675)) |
| [a4ce273e50](angular/angular@a4ce273) | feat | Add the target `RouterStateSnapshot` to `NavigationError` ([#&#8203;46731](angular/angular#46731)) |
| [abe3759e24](angular/angular@abe3759) | fix | allow to return `UrlTree` from `CanMatchFn` ([#&#8203;46455](angular/angular#46455)) |
| [e8c7dd10e9](angular/angular@e8c7dd1) | fix | Ensure `APP_INITIALIZER` of `enabledBlocking` option completes ([#&#8203;46026](angular/angular#46026)) |
| [ce20ed067f](angular/angular@ce20ed0) | fix | Ensure Route injector is created before running CanMatch guards ([#&#8203;46394](angular/angular#46394)) |
| [6a7b818d94](angular/angular@6a7b818) | fix | Ensure target `RouterStateSnapshot` is defined in `NavigationError` ([#&#8203;46842](angular/angular#46842)) |
| [f94c6f433d](angular/angular@f94c6f4) | fix | Expose CanMatchFn as public API ([#&#8203;46394](angular/angular#46394)) |
| [e8ae0fe3e9](angular/angular@e8ae0fe) | fix | Fix cancellation code for canLoad rejections ([#&#8203;46752](angular/angular#46752)) |

##### upgrade

| Commit | Type | Description |
| -- | -- | -- |
| [e9cb0454dc](angular/angular@e9cb045) | feat | more closely align `UpgradeModule#bootstrap()` with `angular.bootstrap()` ([#&#8203;46214](angular/angular#46214)) |

#### Special Thanks

AleksanderBodurri, Alex Rickabaugh, Andrew Kushnir, Andrew Scott, Cédric Exbrayat, Dmitrij Kuba, Dylan Hunn, George Kalpakas, Jessica Janiuk, JiaLiPassion, Joey Perrott, John Vandenberg, JoostK, Keith Li, Or'el Ben-Ya'ir, Paul Gschwendtner, Pawel Kozlowski, SyedAhm3r, arturovt, mariu, markostanimirovic and mgechev

<!-- CHANGELOG SPLIT MARKER -->

### [`v14.0.7`](https://github.com/angular/angular/blob/HEAD/CHANGELOG.md#&#8203;1407-2022-07-20)

[Compare Source](angular/angular@14.0.6...14.0.7)

##### animations

| Commit | Type | Description |
| -- | -- | -- |
| [5bdbb6285b](angular/angular@5bdbb62) | fix | make sure falsy values are added to \_globalTimelineStyles ([#&#8203;46863](angular/angular#46863)) |

##### compiler

| Commit | Type | Description |
| -- | -- | -- |
| [41253f9c46](angular/angular@41253f9) | fix | inputs/outputs incorrectly parsed in jit mode ([#&#8203;46813](angular/angular#46813)) |

##### core

| Commit | Type | Description |
| -- | -- | -- |
| [4e77c7fbf3](angular/angular@4e77c7f) | fix | do not invoke jasmine `done` callback multiple times with `waitForAsync` |

#### Special Thanks

Andrew Kushnir, Andrew Scott, Bob Watson, Cédric Exbrayat, Doug Parker, George Kalpakas, Jessica Janiuk, Kristiyan Kostadinov, Paul Gschwendtner, acvi, dario-piotrowicz, jnizet and piyush132000

<!-- CHANGELOG SPLIT MARKER -->

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzMi4xMTkuMiIsInVwZGF0ZWRJblZlciI6IjMyLjExOS4yIn0=-->

Co-authored-by: cabr2-bot <[email protected]>
Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1472
Reviewed-by: Epsilon_02 <[email protected]>
Co-authored-by: Calciumdibromid Bot <[email protected]>
Co-committed-by: Calciumdibromid Bot <[email protected]>
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Aug 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: merge The PR is ready for merge by the caretaker area: core Issues related to the framework runtime core: di target: minor This PR is targeted for the next minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants