fix(core): export inject() from @angular/core (#22389)

inject() supports the ngInjectableDef-based configuration of the injector
(otherwise known as tree-shakeable services). It was missing from the
exported API of @angular/core, this PR adds it.

The test added here is correct in theory, but may pass accidentally due
to the decorator side-effect replacing the inject() call at runtime. An
upcoming compiler PR will strip reified decorators from the output
entirely.

Fixes #22388

PR Close #22389
This commit is contained in:
Alex Rickabaugh
2018-02-23 09:04:55 -08:00
committed by Alex Eagle
parent 7d65356ae3
commit f8749bfb70
8 changed files with 123 additions and 7 deletions

View File

@ -6,7 +6,25 @@
* found in the LICENSE file at https://angular.io/license
*/
import {InjectionToken, Injector, ReflectiveInjector} from '@angular/core';
import {APP_ROOT_SCOPE, InjectFlags, InjectionToken, Injector, ReflectiveInjector, Type, inject, ɵsetCurrentInjector as setCurrentInjector} from '@angular/core';
class MockRootScopeInjector implements Injector {
constructor(readonly parent: Injector) {}
get<T>(
token: Type<T>|InjectionToken<T>, defaultValue?: any,
flags: InjectFlags = InjectFlags.Default): T {
if ((token as any).ngInjectableDef && (token as any).ngInjectableDef.scope === APP_ROOT_SCOPE) {
const old = setCurrentInjector(this);
try {
return (token as any).ngInjectableDef.factory();
} finally {
setCurrentInjector(old);
}
}
return this.parent.get(token, defaultValue, flags);
}
}
{
describe('injector metadata examples', () => {
@ -37,5 +55,25 @@ import {InjectionToken, Injector, ReflectiveInjector} from '@angular/core';
expect(url).toBe('http://localhost');
// #enddocregion
});
it('injects a tree-shaekable InjectionToken', () => {
class MyDep {}
const injector = new MockRootScopeInjector(ReflectiveInjector.resolveAndCreate([MyDep]));
// #docregion ShakeableInjectionToken
class MyService {
constructor(readonly myDep: MyDep) {}
}
const MY_SERVICE_TOKEN = new InjectionToken<MyService>('Manually constructed MyService', {
scope: APP_ROOT_SCOPE,
factory: () => new MyService(inject(MyDep)),
});
const instance = injector.get(MY_SERVICE_TOKEN);
expect(instance instanceof MyService).toBeTruthy();
expect(instance.myDep instanceof MyDep).toBeTruthy();
// #enddocregion
});
});
}