From 00ffc0352395cdc6364b0aaf6d7dddad64008465 Mon Sep 17 00:00:00 2001 From: Kara Erickson Date: Mon, 29 Apr 2019 15:21:49 -0700 Subject: [PATCH] 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 --- .../core/src/di/injector_compatibility.ts | 3 +- .../core/test/acceptance/providers_spec.ts | 40 ++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/packages/core/src/di/injector_compatibility.ts b/packages/core/src/di/injector_compatibility.ts index 1acd952ed6..dc674c554d 100644 --- a/packages/core/src/di/injector_compatibility.ts +++ b/packages/core/src/di/injector_compatibility.ts @@ -9,6 +9,7 @@ import {Type} from '../interface/type'; import {stringify} from '../util/stringify'; +import {resolveForwardRef} from './forward_ref'; import {InjectionToken} from './injection_token'; import {Injector} from './injector'; import {getInjectableDef, ɵɵInjectableDef} from './interface/defs'; @@ -134,7 +135,7 @@ export function injectRootLimpMode( export function injectArgs(types: (Type| InjectionToken| any[])[]): any[] { const args: any[] = []; for (let i = 0; i < types.length; i++) { - const arg = types[i]; + const arg = resolveForwardRef(types[i]); if (Array.isArray(arg)) { if (arg.length === 0) { throw new Error('Arguments array must have arguments.'); diff --git a/packages/core/test/acceptance/providers_spec.ts b/packages/core/test/acceptance/providers_spec.ts index 41060ea77f..82fca2bae1 100644 --- a/packages/core/test/acceptance/providers_spec.ts +++ b/packages/core/test/acceptance/providers_spec.ts @@ -6,7 +6,7 @@ * 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 {By} from '@angular/platform-browser'; 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'); + }); + + }); + });