diff --git a/packages/core/src/di/r3_injector.ts b/packages/core/src/di/r3_injector.ts index 276e868117..5d7f151393 100644 --- a/packages/core/src/di/r3_injector.ts +++ b/packages/core/src/di/r3_injector.ts @@ -438,7 +438,7 @@ function getUndecoratedInjectableFactory(token: Function) { // just instantiates the zero-arg constructor. const inheritedInjectableDef = getInheritedInjectableDef(token); if (inheritedInjectableDef !== null) { - return inheritedInjectableDef.factory; + return () => inheritedInjectableDef.factory(token as Type); } else { return () => new (token as Type)(); } diff --git a/packages/core/test/di/r3_injector_spec.ts b/packages/core/test/di/r3_injector_spec.ts index 4307985b59..4bf206d3a1 100644 --- a/packages/core/test/di/r3_injector_spec.ts +++ b/packages/core/test/di/r3_injector_spec.ts @@ -62,7 +62,9 @@ describe('InjectorDef-based createInjector()', () => { static ngInjectableDef = ɵɵdefineInjectable({ token: ServiceWithDep, providedIn: null, - factory: () => new ServiceWithDep(ɵɵinject(Service)), + // ChildService is derived from ServiceWithDep, so the factory function here must do the right + // thing and create an instance of the requested type if one is given. + factory: (t?: typeof ServiceWithDep) => new (t || ServiceWithDep)(ɵɵinject(Service)), }); } @@ -163,11 +165,14 @@ describe('InjectorDef-based createInjector()', () => { }); } + class ChildService extends ServiceWithDep {} + class Module { static ngInjectorDef = ɵɵdefineInjector({ factory: () => new Module(), imports: [IntermediateModule], providers: [ + ChildService, ServiceWithDep, ServiceWithOptionalDep, ServiceWithMultiDep, @@ -359,6 +364,11 @@ describe('InjectorDef-based createInjector()', () => { expect(instance).toBe(injector.get(ScopedService)); }); + it('allows injecting an inherited service', () => { + const instance = injector.get(ChildService); + expect(instance instanceof ChildService).toBe(true); + }); + it('does not create instances of a service not in scope', () => { expect(injector.get(WrongScopeService, null)).toBeNull(); });