From 4e413d9240259fca1b1e548c5c405e646f8e68c8 Mon Sep 17 00:00:00 2001 From: Andrew Kushnir Date: Wed, 27 Apr 2022 18:17:25 -0700 Subject: [PATCH] fix(core): support nested arrays of providers in `EnvironmentInjector` (#45789) This commit updates the `EnvironmentInjector` logic to support arrays of providers as an argument(for example, when an injector is created via `createEnvironmentInjector` function). PR Close #45789 --- packages/core/src/di/r3_injector.ts | 6 ++--- .../env_injector_standalone_spec.ts | 25 ++++++++++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/packages/core/src/di/r3_injector.ts b/packages/core/src/di/r3_injector.ts index 4a3194bb652..5f37ccc248a 100644 --- a/packages/core/src/di/r3_injector.ts +++ b/packages/core/src/di/r3_injector.ts @@ -14,7 +14,7 @@ import {Type} from '../interface/type'; import {getComponentDef} from '../render3/definition'; import {FactoryFn, getFactoryDef} from '../render3/definition_factory'; import {throwCyclicDependencyError, throwInvalidProviderError, throwMixedMultiProviderError} from '../render3/errors_di'; -import {flatten, newArray} from '../util/array_utils'; +import {deepForEach, flatten, newArray} from '../util/array_utils'; import {EMPTY_ARRAY} from '../util/empty'; import {stringify} from '../util/stringify'; @@ -125,9 +125,9 @@ export class R3Injector extends EnvironmentInjector { readonly scopes: Set) { super(); // Start off by creating Records for every provider. - for (const provider of providers) { + deepForEach(providers, provider => { this.processProvider(provider as SingleProvider); - } + }); // Make sure the INJECTOR token provides this injector. this.records.set(INJECTOR, makeRecord(undefined, this)); diff --git a/packages/core/test/acceptance/env_injector_standalone_spec.ts b/packages/core/test/acceptance/env_injector_standalone_spec.ts index f98d857da30..937ba941ef6 100644 --- a/packages/core/test/acceptance/env_injector_standalone_spec.ts +++ b/packages/core/test/acceptance/env_injector_standalone_spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Component, createEnvironmentInjector, importProvidersFrom, NgModule} from '@angular/core'; +import {Component, createEnvironmentInjector, importProvidersFrom, InjectionToken, NgModule} from '@angular/core'; describe('environement injector and standalone components', () => { it('should see providers from modules imported by standalone components', () => { @@ -70,4 +70,27 @@ describe('environement injector and standalone components', () => { expect(services.length).toBe(1); }); + + it('should support nested arrays of providers', () => { + const A = new InjectionToken('A'); + const B = new InjectionToken('B'); + const C = new InjectionToken('C'); + const MULTI = new InjectionToken('D'); + + const providers = [ + {provide: MULTI, useValue: 1, multi: true}, {provide: A, useValue: 'A'}, // + [ + {provide: B, useValue: 'B'}, + [ + {provide: C, useValue: 'C'}, + {provide: MULTI, useValue: 2, multi: true}, + ] + ] + ]; + const envInjector = createEnvironmentInjector(providers); + expect(envInjector.get(A)).toBe('A'); + expect(envInjector.get(B)).toBe('B'); + expect(envInjector.get(C)).toBe('C'); + expect(envInjector.get(MULTI)).toEqual([1, 2]); + }); });