fix(ivy): support forward refs in provider deps (#30201)
Currently, we are not properly resolving forward refs when they appear in deps for providers created with the useFactory strategy. This commit wraps provider deps in the resolveForwardRef call so the tokens are passed into the inject function as expected. PR Close #30201
This commit is contained in:
parent
e53cf81689
commit
00ffc03523
|
@ -9,6 +9,7 @@
|
||||||
import {Type} from '../interface/type';
|
import {Type} from '../interface/type';
|
||||||
import {stringify} from '../util/stringify';
|
import {stringify} from '../util/stringify';
|
||||||
|
|
||||||
|
import {resolveForwardRef} from './forward_ref';
|
||||||
import {InjectionToken} from './injection_token';
|
import {InjectionToken} from './injection_token';
|
||||||
import {Injector} from './injector';
|
import {Injector} from './injector';
|
||||||
import {getInjectableDef, ɵɵInjectableDef} from './interface/defs';
|
import {getInjectableDef, ɵɵInjectableDef} from './interface/defs';
|
||||||
|
@ -134,7 +135,7 @@ export function injectRootLimpMode<T>(
|
||||||
export function injectArgs(types: (Type<any>| InjectionToken<any>| any[])[]): any[] {
|
export function injectArgs(types: (Type<any>| InjectionToken<any>| any[])[]): any[] {
|
||||||
const args: any[] = [];
|
const args: any[] = [];
|
||||||
for (let i = 0; i < types.length; i++) {
|
for (let i = 0; i < types.length; i++) {
|
||||||
const arg = types[i];
|
const arg = resolveForwardRef(types[i]);
|
||||||
if (Array.isArray(arg)) {
|
if (Array.isArray(arg)) {
|
||||||
if (arg.length === 0) {
|
if (arg.length === 0) {
|
||||||
throw new Error('Arguments array must have arguments.');
|
throw new Error('Arguments array must have arguments.');
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Component, Directive, Inject, Injectable, InjectionToken} from '@angular/core';
|
import {Component, Directive, Inject, Injectable, InjectionToken, NgModule, forwardRef} from '@angular/core';
|
||||||
import {TestBed, async, inject} from '@angular/core/testing';
|
import {TestBed, async, inject} from '@angular/core/testing';
|
||||||
import {By} from '@angular/platform-browser';
|
import {By} from '@angular/platform-browser';
|
||||||
import {onlyInIvy} from '@angular/private/testing';
|
import {onlyInIvy} from '@angular/private/testing';
|
||||||
|
@ -283,4 +283,42 @@ describe('providers', () => {
|
||||||
})));
|
})));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('forward refs', () => {
|
||||||
|
|
||||||
|
it('should support forward refs in provider deps', () => {
|
||||||
|
class MyService {
|
||||||
|
constructor(public dep: {value: string}) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OtherService {
|
||||||
|
value = 'one';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'app-comp', template: ``})
|
||||||
|
class AppComp {
|
||||||
|
constructor(public myService: MyService) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
providers: [
|
||||||
|
OtherService, {
|
||||||
|
provide: MyService,
|
||||||
|
useFactory: (dep: {value: string}) => new MyService(dep),
|
||||||
|
deps: [forwardRef(() => OtherService)]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
declarations: [AppComp]
|
||||||
|
})
|
||||||
|
class MyModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({imports: [MyModule]});
|
||||||
|
|
||||||
|
const fixture = TestBed.createComponent(AppComp);
|
||||||
|
expect(fixture.componentInstance.myService.dep.value).toBe('one');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue