diff --git a/packages/core/src/render3/instructions/di.ts b/packages/core/src/render3/instructions/di.ts index 49f60e7a1f..7bb92341a7 100644 --- a/packages/core/src/render3/instructions/di.ts +++ b/packages/core/src/render3/instructions/di.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import {InjectFlags, InjectionToken, resolveForwardRef} from '../../di'; +import {ɵɵinject} from '../../di/injector_compatibility'; import {Type} from '../../interface/type'; import {getOrCreateInjectable, injectAttributeImpl} from '../di'; import {TContainerNode, TElementContainerNode, TElementNode} from '../interfaces/node'; @@ -40,9 +41,14 @@ export function ɵɵdirectiveInject(token: Type| InjectionToken, flags: export function ɵɵdirectiveInject( token: Type| InjectionToken, flags = InjectFlags.Default): T|null { token = resolveForwardRef(token); + const lView = getLView(); + // Fall back to inject() if view hasn't been created. This situation can happen in tests + // if inject utilities are used before bootstrapping. + if (lView == null) return ɵɵinject(token, flags); + return getOrCreateInjectable( - getPreviousOrParentTNode() as TElementNode | TContainerNode | TElementContainerNode, - getLView(), token, flags); + getPreviousOrParentTNode() as TElementNode | TContainerNode | TElementContainerNode, lView, + token, flags); } /** diff --git a/packages/core/test/acceptance/providers_spec.ts b/packages/core/test/acceptance/providers_spec.ts index 9f91576bb8..41060ea77f 100644 --- a/packages/core/test/acceptance/providers_spec.ts +++ b/packages/core/test/acceptance/providers_spec.ts @@ -7,7 +7,7 @@ */ import {Component, Directive, Inject, Injectable, InjectionToken} from '@angular/core'; -import {TestBed} from '@angular/core/testing'; +import {TestBed, async, inject} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; import {onlyInIvy} from '@angular/private/testing'; @@ -271,5 +271,16 @@ describe('providers', () => { const myCompInstance = fixture.debugElement.query(By.css('div')).injector.get(MyDir); expect(myCompInstance.svc.value).toEqual('some value'); }); + + describe('injection without bootstrapping', () => { + beforeEach(() => { + TestBed.configureTestingModule({declarations: [MyComp], providers: [MyComp, MyService]}); + }); + + it('should support injecting without bootstrapping', + async(inject([MyComp, MyService], (comp: MyComp, service: MyService) => { + expect(comp.svc.value).toEqual('some value'); + }))); + }); }); }); diff --git a/packages/core/test/bundling/todo/bundle.golden_symbols.json b/packages/core/test/bundling/todo/bundle.golden_symbols.json index 8b4cd066a4..5aa942157e 100644 --- a/packages/core/test/bundling/todo/bundle.golden_symbols.json +++ b/packages/core/test/bundling/todo/bundle.golden_symbols.json @@ -359,6 +359,9 @@ { "name": "_c9" }, + { + "name": "_currentInjector" + }, { "name": "_currentNamespace" }, @@ -902,6 +905,9 @@ { "name": "injectElementRef" }, + { + "name": "injectInjectorOnly" + }, { "name": "injectRootLimpMode" }, @@ -1355,6 +1361,9 @@ { "name": "ɵɵgetCurrentView" }, + { + "name": "ɵɵinject" + }, { "name": "ɵɵinterpolation1" },