From bec5c5fdad9e1d326e43ad5c4f9f5e17f135b66f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=A1ko=20Hevery?= Date: Mon, 15 Aug 2016 19:37:42 -0700 Subject: [PATCH] refactor(Provider): remove deprecated provider/bind API (#10652) Closes #9751 BREAKING CHANGE: These forms of providers are no longer accepted: bind(MyClass).toFactory(...) new Provider(MyClass, toFactory: ...) We now only accept: {provider: MyClass, toFactory: ...} --- .../@angular/common/src/common_directives.ts | 5 +- .../compiler-cli/src/static_reflector.ts | 3 +- modules/@angular/compiler/core_private.ts | 2 - .../@angular/compiler/src/compile_metadata.ts | 27 + .../compiler/src/metadata_resolver.ts | 16 +- .../@angular/compiler/src/runtime_compiler.ts | 8 +- modules/@angular/core/private_export.ts | 7 +- .../differs/iterable_differs.ts | 5 +- .../differs/keyvalue_differs.ts | 5 +- modules/@angular/core/src/di.ts | 2 +- modules/@angular/core/src/di/provider.ts | 646 ++++++++---------- modules/@angular/core/src/di/provider_util.ts | 17 - .../core/src/di/reflective_exceptions.ts | 6 +- .../core/src/di/reflective_injector.ts | 18 +- .../core/src/di/reflective_provider.ts | 37 +- .../src/linker/ng_module_factory_loader.ts | 2 +- .../core/src/platform_core_providers.ts | 3 +- .../differs/iterable_differs_spec.ts | 2 +- modules/@angular/core/test/di/binding_spec.ts | 30 - .../core/test/forward_ref_integration_spec.ts | 2 +- .../test/linker/ng_module_integration_spec.ts | 61 +- .../linker/view_injector_integration_spec.ts | 2 +- modules/@angular/core/testing/test_bed.ts | 6 +- modules/@angular/core/testing/testing.ts | 4 +- .../@angular/core/testing/testing_internal.ts | 1 - .../@angular/docs/web_workers/web_workers.md | 24 +- .../compiler/ts/url_resolver/url_resolver.ts | 1 - .../platform-browser-dynamic/index.ts | 18 +- .../test/testing_public_browser_spec.ts | 4 +- .../platform-browser/private_export.ts | 2 + .../@angular/platform-browser/src/browser.ts | 5 +- .../platform-browser/src/worker_render.ts | 7 +- .../test/browser/bootstrap_spec.ts | 3 +- .../test/browser/tools/spies.ts | 2 +- .../test/testing_public_spec.ts | 3 +- .../shared/service_message_broker_spec.ts | 1 - .../platform-browser/testing/browser.ts | 5 +- .../@angular/platform-server/src/server.ts | 2 +- .../@angular/upgrade/src/upgrade_adapter.ts | 2 +- modules/benchpress/benchpress.ts | 1 - modules/benchpress/common.ts | 2 +- modules/benchpress/src/metric/user_metric.ts | 11 +- .../test/metric/user_metric_spec.ts | 10 +- tools/public_api_guard/common/index.d.ts | 2 +- tools/public_api_guard/core/index.d.ts | 106 ++- .../platform-browser-dynamic/index.d.ts | 6 +- .../platform-browser/index.d.ts | 2 +- 47 files changed, 497 insertions(+), 639 deletions(-) delete mode 100644 modules/@angular/core/src/di/provider_util.ts delete mode 100644 modules/@angular/core/test/di/binding_spec.ts diff --git a/modules/@angular/common/src/common_directives.ts b/modules/@angular/common/src/common_directives.ts index 0539388de7..a7786d661f 100644 --- a/modules/@angular/common/src/common_directives.ts +++ b/modules/@angular/common/src/common_directives.ts @@ -6,8 +6,11 @@ * found in the LICENSE file at https://angular.io/license */ +import {Provider} from '@angular/core'; + import {CORE_DIRECTIVES} from './directives'; + /** * A collection of Angular core directives that are likely to be used in each and every Angular * application. This includes core directives (e.g., NgIf and NgFor), and forms directives (e.g., @@ -53,4 +56,4 @@ import {CORE_DIRECTIVES} from './directives'; * * @experimental Contains forms which are experimental. */ -export const COMMON_DIRECTIVES: any[] = CORE_DIRECTIVES; +export const COMMON_DIRECTIVES: Provider[] = CORE_DIRECTIVES; diff --git a/modules/@angular/compiler-cli/src/static_reflector.ts b/modules/@angular/compiler-cli/src/static_reflector.ts index be699ddc57..3713c4b4dd 100644 --- a/modules/@angular/compiler-cli/src/static_reflector.ts +++ b/modules/@angular/compiler-cli/src/static_reflector.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {AttributeMetadata, ComponentMetadata, ContentChildMetadata, ContentChildrenMetadata, DirectiveMetadata, HostBindingMetadata, HostListenerMetadata, HostMetadata, InjectMetadata, InjectableMetadata, InputMetadata, NgModuleMetadata, OptionalMetadata, OutputMetadata, PipeMetadata, Provider, QueryMetadata, SelfMetadata, SkipSelfMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata, animate, group, keyframes, sequence, state, style, transition, trigger} from '@angular/core'; +import {AttributeMetadata, ComponentMetadata, ContentChildMetadata, ContentChildrenMetadata, DirectiveMetadata, HostBindingMetadata, HostListenerMetadata, HostMetadata, InjectMetadata, InjectableMetadata, InputMetadata, NgModuleMetadata, OptionalMetadata, OutputMetadata, PipeMetadata, QueryMetadata, SelfMetadata, SkipSelfMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata, animate, group, keyframes, sequence, state, style, transition, trigger} from '@angular/core'; import {ReflectorReader} from './core_private'; @@ -175,7 +175,6 @@ export class StaticReflector implements ReflectorReader { const {coreDecorators, diDecorators, diMetadata, diOpaqueToken, animationMetadata, provider} = this.host.angularImportLocations(); this.opaqueToken = this.host.findDeclaration(diOpaqueToken, 'OpaqueToken'); - this.registerDecoratorOrConstructor(this.host.findDeclaration(provider, 'Provider'), Provider); this.registerDecoratorOrConstructor( this.host.findDeclaration(diDecorators, 'Host'), HostMetadata); diff --git a/modules/@angular/compiler/core_private.ts b/modules/@angular/compiler/core_private.ts index 590a9cffec..13466581bf 100644 --- a/modules/@angular/compiler/core_private.ts +++ b/modules/@angular/compiler/core_private.ts @@ -46,8 +46,6 @@ export var ValueUnwrapper: typeof t.ValueUnwrapper = r.ValueUnwrapper; export var TemplateRef_: typeof t.TemplateRef_ = r.TemplateRef_; export type RenderDebugInfo = t.RenderDebugInfo; export var RenderDebugInfo: typeof t.RenderDebugInfo = r.RenderDebugInfo; -export var createProvider: typeof t.createProvider = r.createProvider; -export var isProviderLiteral: typeof t.isProviderLiteral = r.isProviderLiteral; export var EMPTY_ARRAY: typeof t.EMPTY_ARRAY = r.EMPTY_ARRAY; export var EMPTY_MAP: typeof t.EMPTY_MAP = r.EMPTY_MAP; export var pureProxy1: typeof t.pureProxy1 = r.pureProxy1; diff --git a/modules/@angular/compiler/src/compile_metadata.ts b/modules/@angular/compiler/src/compile_metadata.ts index 89ec50b248..17b5f45c66 100644 --- a/modules/@angular/compiler/src/compile_metadata.ts +++ b/modules/@angular/compiler/src/compile_metadata.ts @@ -720,3 +720,30 @@ export interface StaticSymbol { name: string; filePath: string; } + +export class ProviderMeta { + token: any; + useClass: Type; + useValue: any; + useExisting: any; + useFactory: Function; + dependencies: Object[]; + multi: boolean; + + constructor(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}: { + useClass?: Type, + useValue?: any, + useExisting?: any, + useFactory?: Function, + deps?: Object[], + multi?: boolean + }) { + this.token = token; + this.useClass = useClass; + this.useValue = useValue; + this.useExisting = useExisting; + this.useFactory = useFactory; + this.dependencies = deps; + this.multi = !!multi; + } +} diff --git a/modules/@angular/compiler/src/metadata_resolver.ts b/modules/@angular/compiler/src/metadata_resolver.ts index 10aabe837e..aed3736c3a 100644 --- a/modules/@angular/compiler/src/metadata_resolver.ts +++ b/modules/@angular/compiler/src/metadata_resolver.ts @@ -8,7 +8,7 @@ import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, AttributeMetadata, ChangeDetectionStrategy, ComponentMetadata, HostMetadata, InjectMetadata, Injectable, ModuleWithProviders, OptionalMetadata, Provider, QueryMetadata, SchemaMetadata, SelfMetadata, SkipSelfMetadata, Type, ViewQueryMetadata, resolveForwardRef} from '@angular/core'; -import {Console, LIFECYCLE_HOOKS_VALUES, ReflectorReader, createProvider, isProviderLiteral, reflector} from '../core_private'; +import {Console, LIFECYCLE_HOOKS_VALUES, ReflectorReader, reflector} from '../core_private'; import {StringMapWrapper} from '../src/facade/collection'; import {assertArrayOfStrings, assertInterpolationSymbols} from './assertions'; @@ -616,18 +616,18 @@ export class CompileMetadataResolver { return compileToken; } - getProvidersMetadata(providers: any[], targetEntryComponents: cpl.CompileTypeMetadata[]): + getProvidersMetadata(providers: Provider[], targetEntryComponents: cpl.CompileTypeMetadata[]): Array { const compileProviders: Array = []; - providers.forEach((provider) => { + providers.forEach((provider: any) => { provider = resolveForwardRef(provider); - if (isProviderLiteral(provider)) { - provider = createProvider(provider); + if (provider && typeof provider == 'object' && provider.hasOwnProperty('provide')) { + provider = new cpl.ProviderMeta(provider.provide, provider); } let compileProvider: cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[]; if (isArray(provider)) { compileProvider = this.getProvidersMetadata(provider, targetEntryComponents); - } else if (provider instanceof Provider) { + } else if (provider instanceof cpl.ProviderMeta) { let tokenMeta = this.getTokenMetadata(provider.token); if (tokenMeta.equalsTo(identifierToken(Identifiers.ANALYZE_FOR_ENTRY_COMPONENTS))) { targetEntryComponents.push(...this._getEntryComponentsFromProvider(provider)); @@ -647,7 +647,7 @@ export class CompileMetadataResolver { return compileProviders; } - private _getEntryComponentsFromProvider(provider: Provider): cpl.CompileTypeMetadata[] { + private _getEntryComponentsFromProvider(provider: cpl.ProviderMeta): cpl.CompileTypeMetadata[] { let components: cpl.CompileTypeMetadata[] = []; let collectedIdentifiers: cpl.CompileIdentifierMetadata[] = []; if (provider.useFactory || provider.useExisting || provider.useClass) { @@ -667,7 +667,7 @@ export class CompileMetadataResolver { return components; } - getProviderMetadata(provider: Provider): cpl.CompileProviderMetadata { + getProviderMetadata(provider: cpl.ProviderMeta): cpl.CompileProviderMetadata { var compileDeps: cpl.CompileDiDependencyMetadata[]; var compileTypeMetadata: cpl.CompileTypeMetadata = null; var compileFactoryMetadata: cpl.CompileFactoryMetadata = null; diff --git a/modules/@angular/compiler/src/runtime_compiler.ts b/modules/@angular/compiler/src/runtime_compiler.ts index c9b6e48421..ef06c8af8b 100644 --- a/modules/@angular/compiler/src/runtime_compiler.ts +++ b/modules/@angular/compiler/src/runtime_compiler.ts @@ -6,11 +6,11 @@ * found in the LICENSE file at https://angular.io/license */ -import {Compiler, ComponentFactory, ComponentResolver, ComponentStillLoadingError, Injectable, Injector, ModuleWithComponentFactories, NgModuleFactory, OptionalMetadata, Provider, SchemaMetadata, SkipSelfMetadata, Type} from '@angular/core'; +import {Compiler, ComponentFactory, ComponentResolver, ComponentStillLoadingError, Injectable, Injector, ModuleWithComponentFactories, NgModuleFactory, OptionalMetadata, SchemaMetadata, SkipSelfMetadata, Type} from '@angular/core'; import {Console} from '../core_private'; -import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeMetadata, createHostComponentMeta} from './compile_metadata'; +import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeMetadata, ProviderMeta, createHostComponentMeta} from './compile_metadata'; import {CompilerConfig} from './config'; import {DirectiveNormalizer} from './directive_normalizer'; import {BaseException} from './facade/exceptions'; @@ -129,12 +129,12 @@ export class RuntimeCompiler implements Compiler { new ModuleBoundCompiler(this, moduleMeta.type.runtime, parentResolver, this._console); // Always provide a bound Compiler and ComponentResolver const extraProviders = [ - this._metadataResolver.getProviderMetadata(new Provider(Compiler, { + this._metadataResolver.getProviderMetadata(new ProviderMeta(Compiler, { useFactory: boundCompilerFactory, deps: [[new OptionalMetadata(), new SkipSelfMetadata(), ComponentResolver]] })), this._metadataResolver.getProviderMetadata( - new Provider(ComponentResolver, {useExisting: Compiler})) + new ProviderMeta(ComponentResolver, {useExisting: Compiler})) ]; var compileResult = this._ngModuleCompiler.compile(moduleMeta, extraProviders); compileResult.dependencies.forEach((dep) => { diff --git a/modules/@angular/core/private_export.ts b/modules/@angular/core/private_export.ts index 16d776d45c..0c41ed9da2 100644 --- a/modules/@angular/core/private_export.ts +++ b/modules/@angular/core/private_export.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {Provider} from './index'; import {ANY_STATE as ANY_STATE_, DEFAULT_STATE as DEFAULT_STATE_, EMPTY_STATE as EMPTY_STATE_, FILL_STYLE_FLAG as FILL_STYLE_FLAG_} from './src/animation/animation_constants'; import {AnimationGroupPlayer as AnimationGroupPlayer_} from './src/animation/animation_group_player'; import {AnimationKeyframe as AnimationKeyframe_} from './src/animation/animation_keyframe'; @@ -18,7 +17,7 @@ import * as change_detection_util from './src/change_detection/change_detection_ import * as constants from './src/change_detection/constants'; import * as console from './src/console'; import * as debug from './src/debug/debug_renderer'; -import * as provider_util from './src/di/provider_util'; +import * as provider from './src/di/provider'; import * as reflective_provider from './src/di/reflective_provider'; import * as component_factory_resolver from './src/linker/component_factory_resolver'; import * as component_resolver from './src/linker/component_resolver'; @@ -83,8 +82,6 @@ export declare namespace __core_private_types__ { export var makeDecorator: typeof decorators.makeDecorator; export type DebugDomRootRenderer = debug.DebugDomRootRenderer; export var DebugDomRootRenderer: typeof debug.DebugDomRootRenderer; - export var createProvider: typeof provider_util.createProvider; - export var isProviderLiteral: typeof provider_util.isProviderLiteral; export var EMPTY_ARRAY: typeof view_utils.EMPTY_ARRAY; export var EMPTY_MAP: typeof view_utils.EMPTY_MAP; export var pureProxy1: typeof view_utils.pureProxy1; @@ -158,8 +155,6 @@ export var __core_private__ = { ReflectionCapabilities: reflection_capabilities.ReflectionCapabilities, makeDecorator: decorators.makeDecorator, DebugDomRootRenderer: debug.DebugDomRootRenderer, - createProvider: provider_util.createProvider, - isProviderLiteral: provider_util.isProviderLiteral, EMPTY_ARRAY: view_utils.EMPTY_ARRAY, EMPTY_MAP: view_utils.EMPTY_MAP, pureProxy1: view_utils.pureProxy1, diff --git a/modules/@angular/core/src/change_detection/differs/iterable_differs.ts b/modules/@angular/core/src/change_detection/differs/iterable_differs.ts index 106152a078..2394e0b7a4 100644 --- a/modules/@angular/core/src/change_detection/differs/iterable_differs.ts +++ b/modules/@angular/core/src/change_detection/differs/iterable_differs.ts @@ -80,7 +80,8 @@ export class IterableDiffers { * ``` */ static extend(factories: IterableDifferFactory[]): Provider { - return new Provider(IterableDiffers, { + return { + provide: IterableDiffers, useFactory: (parent: IterableDiffers) => { if (isBlank(parent)) { // Typically would occur when calling IterableDiffers.extend inside of dependencies passed @@ -92,7 +93,7 @@ export class IterableDiffers { }, // Dependency technically isn't optional, but we can provide a better error message this way. deps: [[IterableDiffers, new SkipSelfMetadata(), new OptionalMetadata()]] - }); + }; } find(iterable: any): IterableDifferFactory { diff --git a/modules/@angular/core/src/change_detection/differs/keyvalue_differs.ts b/modules/@angular/core/src/change_detection/differs/keyvalue_differs.ts index f5bb58640f..196bb86748 100644 --- a/modules/@angular/core/src/change_detection/differs/keyvalue_differs.ts +++ b/modules/@angular/core/src/change_detection/differs/keyvalue_differs.ts @@ -70,7 +70,8 @@ export class KeyValueDiffers { * ``` */ static extend(factories: KeyValueDifferFactory[]): Provider { - return new Provider(KeyValueDiffers, { + return { + provide: KeyValueDiffers, useFactory: (parent: KeyValueDiffers) => { if (isBlank(parent)) { // Typically would occur when calling KeyValueDiffers.extend inside of dependencies passed @@ -82,7 +83,7 @@ export class KeyValueDiffers { }, // Dependency technically isn't optional, but we can provide a better error message this way. deps: [[KeyValueDiffers, new SkipSelfMetadata(), new OptionalMetadata()]] - }); + }; } find(kv: Object): KeyValueDifferFactory { diff --git a/modules/@angular/core/src/di.ts b/modules/@angular/core/src/di.ts index 87d2ad9ed9..87fae3a288 100644 --- a/modules/@angular/core/src/di.ts +++ b/modules/@angular/core/src/di.ts @@ -22,7 +22,7 @@ export {forwardRef, resolveForwardRef, ForwardRefFn} from './di/forward_ref'; export {Injector} from './di/injector'; export {ReflectiveInjector} from './di/reflective_injector'; -export {Binding, ProviderBuilder, bind, Provider, provide} from './di/provider'; +export {Provider, TypeProvider, ValueProvider, ClassProvider, ExistingProvider, FactoryProvider} from './di/provider'; export {ResolvedReflectiveBinding, ResolvedReflectiveFactory, ResolvedReflectiveProvider} from './di/reflective_provider'; export {ReflectiveKey} from './di/reflective_key'; export {NoProviderError, AbstractProviderError, CyclicDependencyError, InstantiationError, InvalidProviderError, NoAnnotationError, OutOfBoundsError} from './di/reflective_exceptions'; diff --git a/modules/@angular/core/src/di/provider.ts b/modules/@angular/core/src/di/provider.ts index 03dbe7cfa8..74cbce3330 100644 --- a/modules/@angular/core/src/di/provider.ts +++ b/modules/@angular/core/src/di/provider.ts @@ -6,410 +6,344 @@ * found in the LICENSE file at https://angular.io/license */ -import {BaseException} from '../facade/exceptions'; -import {isBlank, isFunction, isType, normalizeBool, stringify} from '../facade/lang'; import {Type} from '../type'; - /** - * Describes how the {@link Injector} should instantiate a given token. + * Configures the {@link Injector} to return an instance of `Type` when `Type' is used as token. * - * See {@link provide}. - * - * ### Example ([live demo](http://plnkr.co/edit/GNAyj6K6PfYg2NBzgwZ5?p%3Dpreview&p=preview)) + * Create an instance by invoking the `new` operator and supplying additional arguments. + * This form is a short form of `TypeProvider`; * + * ### Example * ```javascript - * var injector = Injector.resolveAndCreate([ - * new Provider("message", { useValue: 'Hello' }) + * @Injectable() + * class Greeting { + * text: 'Hello'; + * } + * + * @Injectable() + * class MyClass { + * greeting:string; + * constructor(greeting: Greeting) { + * this.greeting = greeting.text; + * } + * } + * + * const injector = Injector.resolveAndCreate([ + * Greeting, // Shorthand for { provide: Greeting, useClass: Greeting } + * MyClass // Shorthand for { provide: MyClass, useClass: MyClass } * ]); * - * expect(injector.get("message")).toEqual('Hello'); + * const myClass: MyClass = injector.get(MyClass); + * expect(myClass.greeting).toEqual('Hello'); * ``` - * @deprecated + * + * @stable */ -export class Provider { +export interface TypeProvider extends Type {} + +/** + * Configures the {@link Injector} to return a value for a token. + * + * ### Example + * const injector = Injector.resolveAndCreate([ + * {provide: String, useValue: 'Hello'} + * ]); + * + * expect(injector.get(String)).toEqual('Hello'); + * ``` + * @stable + */ +export interface ValueProvider { /** - * Token used when retrieving this provider. Usually, it is a type {@link Type}. + * An injection token. (Typically an instance of `Type` or `OpaqueToken`, but can be `any`). */ - token: any; + provide: any; /** - * Binds a DI token to an implementation class. - * - * ### Example ([live demo](http://plnkr.co/edit/RSTG86qgmoxCyj9SWPwY?p=preview)) - * - * Because `useExisting` and `useClass` are often confused, the example contains - * both use cases for easy comparison. - * - * ```typescript - * class Vehicle {} - * - * class Car extends Vehicle {} - * - * var injectorClass = Injector.resolveAndCreate([ - * Car, - * {provide: Vehicle, useClass: Car } - * ]); - * var injectorAlias = Injector.resolveAndCreate([ - * Car, - * {provide: Vehicle, useExisting: Car } - * ]); - * - * expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car)); - * expect(injectorClass.get(Vehicle) instanceof Car).toBe(true); - * - * expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car)); - * expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true); - * ``` - */ - useClass: Type; - - /** - * Binds a DI token to a value. - * - * ### Example ([live demo](http://plnkr.co/edit/UFVsMVQIDe7l4waWziES?p=preview)) - * - * ```javascript - * var injector = Injector.resolveAndCreate([ - * new Provider("message", { useValue: 'Hello' }) - * ]); - * - * expect(injector.get("message")).toEqual('Hello'); - * ``` + * The value to inject. */ useValue: any; /** - * Binds a DI token to an existing token. + * If true, than injector returns an array of instances. This is useful to allow multiple + * providers spread across many files to provide configuration information to a common token. * - * {@link Injector} returns the same instance as if the provided token was used. - * This is in contrast to `useClass` where a separate instance of `useClass` is returned. + * ### Example + * ```javascript + * var locale = new OpaqueToken('local'); * - * ### Example ([live demo](http://plnkr.co/edit/QsatsOJJ6P8T2fMe9gr8?p=preview)) - * - * Because `useExisting` and `useClass` are often confused the example contains - * both use cases for easy comparison. - * - * ```typescript - * class Vehicle {} - * - * class Car extends Vehicle {} - * - * var injectorAlias = Injector.resolveAndCreate([ - * Car, - * {provide: Vehicle, useExisting: Car } - * ]); - * var injectorClass = Injector.resolveAndCreate([ - * Car, - * {provide: Vehicle, useClass: Car } + * const injector = Injector.resolveAndCreate([ + * { provide: locale, useValue: 'en' }, + * { provide: locale, useValue: 'sk' }, * ]); * - * expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car)); - * expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true); - * - * expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car)); - * expect(injectorClass.get(Vehicle) instanceof Car).toBe(true); + * const locales: string[] = injector.get(locale); + * expect(locales).toEqual(['en', 'sk']); * ``` */ + multi?: boolean; +} + +/** + * Configures the {@link Injector} to return an instance of `useClass` for a token. + * + * ### Example + * ```javascript + * abstract class Shape { + * name: string; + * } + * + * class Square extends Shape { + * name = 'square'; + * } + * + * const injector = Injector.resolveAndCreate([ + * {provide: Shape, useClass: Square} + * ]); + * + * const shape: Shape = injector.get(Shape); + * expect(shape.name).toEqual('square'); + * expect(shape instanceof Square).toBe(true); + * ``` + * + * Note that following is not equal: + * ```javascript + * class Greeting { + * salutation = 'Hello'; + * } + * + * class FormalGreeting extends Greeting { + * salutation = 'Greetings'; + * } + * + * const injector = Injector.resolveAndCreate([ + * FormalGreeting, + * {provide: Greeting, useClass: FormalGreeting} + * ]); + * + * // The injector returns different instances. + * // See: {provide: ?, useExisting: ?} if you want the same instance. + * expect(injector.get(FormalGreeting)).not.toBe(injector.get(Greeting)); + * ``` + * + * @stable + */ +export interface ClassProvider { + /** + * An injection token. (Typically an instance of `Type` or `OpaqueToken`, but can be `any`). + */ + provide: any; + + /** + * Class to instantiate for the `token`. + */ + useClass: Type; + + /** + * If true, than injector returns an array of instances. This is useful to allow multiple + * providers spread across many files to provide configuration information to a common token. + * + * ### Example + * ```javascript + * abstract class Locale { + * name: string; + * }; + * + * @Injectable() + * class EnLocale extends Locale { + * name: 'en'; + * }; + * + * @Injectable() + * class SkLocale extends Locale { + * name: 'sk'; + * }; + * + * const injector = Injector.resolveAndCreate([ + * { provide: Locale, useValue: EnLocale, multi: true }, + * { provide: Locale, useValue: SkLocale, multi: true }, + * ]); + * + * const locales: Locale[] = injector.get(Locale); + * const localeNames: string[] = locals.map((l) => l.name); + * expect(localeNames).toEqual(['en', 'sk']); + * ``` + */ + multi?: boolean; +} + +/** + * Configures the {@link Injector} to return a value of another `useExisting` token. + * + * ### Example + * ```javascript + * class Greeting { + * salutation = 'Hello'; + * } + * + * class FormalGreeting extends Greeting { + * salutation = 'Greetings'; + * } + * + * const injector = Injector.resolveAndCreate([ + * FormalGreeting, + * {provide: Greeting, useExisting: FormalGreeting} + * ]); + * + * expect(injector.get(Greeting).name).toEqual('Hello'); + * expect(injector.get(FormalGreeting).name).toEqual('Hello'); + * expect(injector.get(Salutation).name).toBe(injector.get(Greeting)); + * ``` + * @stable + */ +export interface ExistingProvider { + /** + * An injection token. (Typically an instance of `Type` or `OpaqueToken`, but can be `any`). + */ + provide: any; + + /** + * Existing `token` to return. (equivalent to `injector.get(useExisting)`) + */ useExisting: any; /** - * Binds a DI token to a function which computes the value. + * If true, than injector returns an array of instances. This is useful to allow multiple + * providers spread across many files to provide configuration information to a common token. * - * ### Example ([live demo](http://plnkr.co/edit/Scoxy0pJNqKGAPZY1VVC?p=preview)) + * ### Example + * ```javascript + * abstract class Locale { + * name: string; + * }; * - * ```typescript - * var injector = Injector.resolveAndCreate([ - * {provide: Number, useFactory: () => { return 1+2; }}, - * new Provider(String, { useFactory: (value) => { return "Value: " + value; }, - * deps: [Number] }) + * @Injectable() + * class EnLocale extends Locale { + * name: 'en'; + * }; + * + * @Injectable() + * class SkLocale extends Locale { + * name: 'sk'; + * }; + * + * const injector = Injector.resolveAndCreate([ + * EnLocale, + * SkLocale + * { provide: Locale, useExisting: EnLocale, multi: true }, + * { provide: Locale, useExisting: SkLocale, multi: true }, * ]); * - * expect(injector.get(Number)).toEqual(3); - * expect(injector.get(String)).toEqual('Value: 3'); + * const locales: Locale[] = injector.get(Locale); + * const localeNames: string[] = locals.map((l) => l.name); + * expect(localeNames).toEqual(['en', 'sk']); * ``` - * - * Used in conjunction with dependencies. + */ + multi?: boolean; +} + +/** + * Configures the {@link Injector} to return a value by invoking a `useFactory` function. + * + * ### Example + * ```javascript + * const HASH = new OpaqueToken('hash'); + * + * const injector = Injector.resolveAndCreate([ + * {provide: Location, useValue: window.location}, + * {provide: HASH, useFactory: (location: Location) => location.hash, deps: [Location]} + * ]); + * + * + * // Assume location is: http://angular.io/#someLocation + * expect(injector.get(HASH)).toEqual('someLocation'); + * `` + * @stable + */ +export interface FactoryProvider { + /** + * An injection token. (Typically an instance of `Type` or `OpaqueToken`, but can be `any`). + */ + provide: any; + + /** + * A function to invoke to create a value for this `token`. The function is invoked with + * resolved values of `token`s in the `deps` field. */ useFactory: Function; /** - * Specifies a set of dependencies - * (as `token`s) which should be injected into the factory function. - * - * ### Example ([live demo](http://plnkr.co/edit/Scoxy0pJNqKGAPZY1VVC?p=preview)) - * - * ```typescript - * var injector = Injector.resolveAndCreate([ - * {provide: Number, useFactory: () => { return 1+2; }}, - * new Provider(String, { useFactory: (value) => { return "Value: " + value; }, - * deps: [Number] }) - * ]); - * - * expect(injector.get(Number)).toEqual(3); - * expect(injector.get(String)).toEqual('Value: 3'); - * ``` - * - * Used in conjunction with `useFactory`. + * A list of `token`s which need to be resolved by the injector. The list of values is than + * used as arguments to the `useFactory` function. */ - dependencies: Object[]; + deps: any[]; - /** @internal */ - _multi: boolean; - - constructor(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}: { - useClass?: Type, - useValue?: any, - useExisting?: any, - useFactory?: Function, - deps?: Object[], - multi?: boolean - }) { - this.token = token; - this.useClass = useClass; - this.useValue = useValue; - this.useExisting = useExisting; - this.useFactory = useFactory; - this.dependencies = deps; - this._multi = multi; - } - - // TODO: Provide a full working example after alpha38 is released. /** - * Creates multiple providers matching the same token (a multi-provider). - * - * Multi-providers are used for creating pluggable service, where the system comes - * with some default providers, and the user can register additional providers. - * The combination of the default providers and the additional providers will be - * used to drive the behavior of the system. + * If true, than injector returns an array of instances. This is useful to allow multiple + * providers spread across many files to provide configuration information to a common token. * * ### Example + * ```javascript + * class Locale { + * constructor(public name: string) {} + * }; + * const PRIMARY = new OpequeToken('primary'); + * const SECONDARY = new OpequeToken('secondary'); * - * ```typescript - * var injector = Injector.resolveAndCreate([ - * new Provider("Strings", { useValue: "String1", multi: true}), - * new Provider("Strings", { useValue: "String2", multi: true}) + * const injector = Injector.resolveAndCreate([ + * { provide: PRIMARY: useValue: 'en'}, + * { provide: SECONDARY: useValue: 'sk'}, + * { provide: Locale, useFactory: (n) => new Locale(n), deps: [PRIMARY], multi: true}, + * { provide: Locale, useFactory: (n) => new Locale(n), deps: [SECONDARY], multi: true}, * ]); * - * expect(injector.get("Strings")).toEqual(["String1", "String2"]); - * ``` - * - * Multi-providers and regular providers cannot be mixed. The following - * will throw an exception: - * - * ```typescript - * var injector = Injector.resolveAndCreate([ - * new Provider("Strings", { useValue: "String1", multi: true }), - * new Provider("Strings", { useValue: "String2"}) - * ]); + * const locales: Locale[] = injector.get(Locale); + * const localeNames: string[] = locals.map((l) => l.name); + * expect(localeNames).toEqual(['en', 'sk']); * ``` */ - get multi(): boolean { return normalizeBool(this._multi); } + multi?: boolean; } /** - * See {@link Provider} instead. + * Describes how the {@link Injector} should be configured. * - * @deprecated + * See {@link TypeProvider}, {@link ValueProvider}, {@link ClassProvider}, {@link ExistingProvider}, + * {@link FactoryProvider}. + * + * ```javascript + * class Greeting { + * salutation = 'Hello'; + * } + * + * class FormalGreeting extends Greeting { + * salutation = 'Greetings'; + * } + * + * abstract class Operation { + * apply(a,b): any; + * } + * + * class AddOperation extends Operation { + * apply(a,b) { return a+b; } + * } + * + * + * const injector = Injector.resolveAndCreate([ + * FormalGreeting, + * {provide: String, useValue: 'Hello World!'}, + * {provide: Greeting, useExisting: FormalGreeting}, + * {provide: Operation, useClass: AddOperation}, + * {provide: Number, useFactory: (op) =>op.apply(1,2), deps: [Operation] } + * ]); + * + * expect(injector.get(FormalGreeting).name).toEqual('Greetings'); + * expect(injector.get(String).name).toEqual('Hello World!'); + * expect(injector.get(Greeting).name).toBe(injector.get(FormalGreeting)); + * expect(injector.get(Number).toEqual(3); + * ``` + * @stable */ -export class Binding extends Provider { - constructor(token: any, {toClass, toValue, toAlias, toFactory, deps, multi}: { - toClass?: Type, - toValue?: any, - toAlias?: any, - toFactory: Function, deps?: Object[], multi?: boolean - }) { - super(token, { - useClass: toClass, - useValue: toValue, - useExisting: toAlias, - useFactory: toFactory, - deps: deps, - multi: multi - }); - } - - /** - * @deprecated - */ - get toClass() { return this.useClass; } - - /** - * @deprecated - */ - get toAlias() { return this.useExisting; } - - /** - * @deprecated - */ - get toFactory() { return this.useFactory; } - - /** - * @deprecated - */ - get toValue() { return this.useValue; } -} - -/** - * Creates a {@link Provider}. - * - * To construct a {@link Provider}, bind a `token` to either a class, a value, a factory function, - * or - * to an existing `token`. - * See {@link ProviderBuilder} for more details. - * - * The `token` is most commonly a class or {@link OpaqueToken}. - * - * @deprecated - */ -export function bind(token: any): ProviderBuilder { - return new ProviderBuilder(token); -} - -/** - * Helper class for the {@link bind} function. - * @deprecated - */ -export class ProviderBuilder { - constructor(public token: any) {} - - /** - * Binds a DI token to a class. - * - * ### Example ([live demo](http://plnkr.co/edit/ZpBCSYqv6e2ud5KXLdxQ?p=preview)) - * - * Because `toAlias` and `toClass` are often confused, the example contains - * both use cases for easy comparison. - * - * ```typescript - * class Vehicle {} - * - * class Car extends Vehicle {} - * - * var injectorClass = Injector.resolveAndCreate([ - * Car, - * {provide: Vehicle, useClass: Car} - * ]); - * var injectorAlias = Injector.resolveAndCreate([ - * Car, - * {provide: Vehicle, useExisting: Car} - * ]); - * - * expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car)); - * expect(injectorClass.get(Vehicle) instanceof Car).toBe(true); - * - * expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car)); - * expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true); - * ``` - */ - toClass(type: Type): Provider { - if (!isType(type)) { - throw new BaseException( - `Trying to create a class provider but "${stringify(type)}" is not a class!`); - } - return new Provider(this.token, {useClass: type}); - } - - /** - * Binds a DI token to a value. - * - * ### Example ([live demo](http://plnkr.co/edit/G024PFHmDL0cJFgfZK8O?p=preview)) - * - * ```typescript - * var injector = Injector.resolveAndCreate([ - * {provide: 'message', useValue: 'Hello'} - * ]); - * - * expect(injector.get('message')).toEqual('Hello'); - * ``` - */ - toValue(value: any): Provider { return new Provider(this.token, {useValue: value}); } - - /** - * Binds a DI token to an existing token. - * - * Angular will return the same instance as if the provided token was used. (This is - * in contrast to `useClass` where a separate instance of `useClass` will be returned.) - * - * ### Example ([live demo](http://plnkr.co/edit/uBaoF2pN5cfc5AfZapNw?p=preview)) - * - * Because `toAlias` and `toClass` are often confused, the example contains - * both use cases for easy comparison. - * - * ```typescript - * class Vehicle {} - * - * class Car extends Vehicle {} - * - * var injectorAlias = Injector.resolveAndCreate([ - * Car, - * {provide: Vehicle, useExisting: Car} - * ]); - * var injectorClass = Injector.resolveAndCreate([ - * Car, - * {provide: Vehicle, useClass: Car}) - * ]); - * - * expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car)); - * expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true); - * - * expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car)); - * expect(injectorClass.get(Vehicle) instanceof Car).toBe(true); - * ``` - */ - toAlias(aliasToken: /*Type*/ any): Provider { - if (isBlank(aliasToken)) { - throw new BaseException(`Can not alias ${stringify(this.token)} to a blank value!`); - } - return new Provider(this.token, {useExisting: aliasToken}); - } - - /** - * Binds a DI token to a function which computes the value. - * - * ### Example ([live demo](http://plnkr.co/edit/OejNIfTT3zb1iBxaIYOb?p=preview)) - * - * ```typescript - * var injector = Injector.resolveAndCreate([ - * {provide: Number, useFactory: () => { return 1+2; }}, - * {provide: String, useFactory: (v) => { return "Value: " + v; }, deps: [Number]} - * ]); - * - * expect(injector.get(Number)).toEqual(3); - * expect(injector.get(String)).toEqual('Value: 3'); - * ``` - */ - toFactory(factory: Function, dependencies?: any[]): Provider { - if (!isFunction(factory)) { - throw new BaseException( - `Trying to create a factory provider but "${stringify(factory)}" is not a function!`); - } - return new Provider(this.token, {useFactory: factory, deps: dependencies}); - } -} - -/** - * Creates a {@link Provider}. - * - * See {@link Provider} for more details. - * - * - * @deprecated - */ -export function provide(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}: { - useClass?: Type, - useValue?: any, - useExisting?: any, - useFactory?: Function, - deps?: Object[], - multi?: boolean -}): Provider { - return new Provider(token, { - useClass: useClass, - useValue: useValue, - useExisting: useExisting, - useFactory: useFactory, - deps: deps, - multi: multi - }); -} +export type Provider = + TypeProvider | ValueProvider | ClassProvider | ExistingProvider | FactoryProvider | any[]; diff --git a/modules/@angular/core/src/di/provider_util.ts b/modules/@angular/core/src/di/provider_util.ts deleted file mode 100644 index 25e9ec653a..0000000000 --- a/modules/@angular/core/src/di/provider_util.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -import {Provider} from './provider'; - -export function isProviderLiteral(obj: any): boolean { - return obj && typeof obj == 'object' && obj.provide; -} - -export function createProvider(obj: any): Provider { - return new Provider(obj.provide, obj); -} diff --git a/modules/@angular/core/src/di/reflective_exceptions.ts b/modules/@angular/core/src/di/reflective_exceptions.ts index 02557f7808..43428e5838 100644 --- a/modules/@angular/core/src/di/reflective_exceptions.ts +++ b/modules/@angular/core/src/di/reflective_exceptions.ts @@ -10,8 +10,6 @@ import {ListWrapper} from '../facade/collection'; import {BaseException, WrappedException} from '../facade/exceptions'; import {isBlank, stringify} from '../facade/lang'; import {Type} from '../type'; - -import {Provider} from './provider'; import {ReflectiveInjector} from './reflective_injector'; import {ReflectiveKey} from './reflective_key'; @@ -273,8 +271,8 @@ export class OutOfBoundsError extends BaseException { * * ```typescript * expect(() => Injector.resolveAndCreate([ - * new Provider("Strings", {useValue: "string1", multi: true}), - * new Provider("Strings", {useValue: "string2", multi: false}) + * { provide: "Strings", useValue: "string1", multi: true}, + * { provide: "Strings", useValue: "string2", multi: false} * ])).toThrowError(); * ``` */ diff --git a/modules/@angular/core/src/di/reflective_injector.ts b/modules/@angular/core/src/di/reflective_injector.ts index 86cc6249ef..46b76b9a10 100644 --- a/modules/@angular/core/src/di/reflective_injector.ts +++ b/modules/@angular/core/src/di/reflective_injector.ts @@ -392,8 +392,7 @@ export abstract class ReflectiveInjector implements Injector { * * See {@link ReflectiveInjector#fromResolvedProviders} for more info. */ - static resolve(providers: Array|Provider|{[k: string]: any}|any[]>): - ResolvedReflectiveProvider[] { + static resolve(providers: Provider[]): ResolvedReflectiveProvider[] { return resolveReflectiveProviders(providers); } @@ -423,9 +422,7 @@ export abstract class ReflectiveInjector implements Injector { * because it needs to resolve the passed-in providers first. * See {@link Injector#resolve} and {@link Injector#fromResolvedProviders}. */ - static resolveAndCreate( - providers: Array|Provider|{[k: string]: any}|any[]>, - parent: Injector = null): ReflectiveInjector { + static resolveAndCreate(providers: Provider[], parent: Injector = null): ReflectiveInjector { var ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers); return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent); } @@ -516,10 +513,7 @@ export abstract class ReflectiveInjector implements Injector { * because it needs to resolve the passed-in providers first. * See {@link Injector#resolve} and {@link Injector#createChildFromResolved}. */ - resolveAndCreateChild(providers: Array|Provider|{[k: string]: any}|any[]>): - ReflectiveInjector { - return unimplemented(); - } + resolveAndCreateChild(providers: Provider[]): ReflectiveInjector { return unimplemented(); } /** * Creates a child injector from previously resolved providers. @@ -574,7 +568,7 @@ export abstract class ReflectiveInjector implements Injector { * expect(car).not.toBe(injector.resolveAndInstantiate(Car)); * ``` */ - resolveAndInstantiate(provider: Type|Provider): any { return unimplemented(); } + resolveAndInstantiate(provider: Provider): any { return unimplemented(); } /** * Instantiates an object using a resolved provider in the context of the injector. @@ -644,7 +638,7 @@ export class ReflectiveInjector_ implements ReflectiveInjector { */ get internalStrategy(): any { return this._strategy; } - resolveAndCreateChild(providers: Array|Provider|any[]>): ReflectiveInjector { + resolveAndCreateChild(providers: Provider[]): ReflectiveInjector { var ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers); return this.createChildFromResolved(ResolvedReflectiveProviders); } @@ -656,7 +650,7 @@ export class ReflectiveInjector_ implements ReflectiveInjector { return inj; } - resolveAndInstantiate(provider: Type|Provider): any { + resolveAndInstantiate(provider: Provider): any { return this.instantiateResolved(ReflectiveInjector.resolve([provider])[0]); } diff --git a/modules/@angular/core/src/di/reflective_provider.ts b/modules/@angular/core/src/di/reflective_provider.ts index 3417773c93..90bea61879 100644 --- a/modules/@angular/core/src/di/reflective_provider.ts +++ b/modules/@angular/core/src/di/reflective_provider.ts @@ -13,12 +13,13 @@ import {Type} from '../type'; import {resolveForwardRef} from './forward_ref'; import {DependencyMetadata, HostMetadata, InjectMetadata, OptionalMetadata, SelfMetadata, SkipSelfMetadata} from './metadata'; -import {Provider, ProviderBuilder, provide} from './provider'; -import {createProvider, isProviderLiteral} from './provider_util'; +import {ClassProvider, ExistingProvider, FactoryProvider, Provider, TypeProvider, ValueProvider} from './provider'; import {InvalidProviderError, MixingMultiProvidersWithRegularProvidersError, NoAnnotationError} from './reflective_exceptions'; import {ReflectiveKey} from './reflective_key'; +interface NormalizedProvider extends TypeProvider, ValueProvider, ClassProvider, ExistingProvider, + FactoryProvider {} /** * `Dependency` is used by the framework to extend DI. @@ -46,7 +47,7 @@ const _EMPTY_LIST: any[] = []; * ### Example ([live demo](http://plnkr.co/edit/RfEnhh8kUEI0G3qsnIeT?p%3Dpreview&p=preview)) * * ```typescript - * var resolvedProviders = Injector.resolve([new Provider('message', {useValue: 'Hello'})]); + * var resolvedProviders = Injector.resolve([{ provide: 'message', useValue: 'Hello' }]); * var injector = Injector.fromResolvedProviders(resolvedProviders); * * expect(injector.get('message')).toEqual('Hello'); @@ -87,7 +88,8 @@ export class ResolvedReflectiveProvider_ implements ResolvedReflectiveBinding { } /** - * An internal resolved representation of a factory function created by resolving {@link Provider}. + * An internal resolved representation of a factory function created by resolving {@link + * Provider}. * @experimental */ export class ResolvedReflectiveFactory { @@ -107,7 +109,7 @@ export class ResolvedReflectiveFactory { /** * Resolve a single provider. */ -export function resolveReflectiveFactory(provider: Provider): ResolvedReflectiveFactory { +function resolveReflectiveFactory(provider: NormalizedProvider): ResolvedReflectiveFactory { var factoryFn: Function; var resolvedDeps: ReflectiveDependency[]; if (isPresent(provider.useClass)) { @@ -119,7 +121,7 @@ export function resolveReflectiveFactory(provider: Provider): ResolvedReflective resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))]; } else if (isPresent(provider.useFactory)) { factoryFn = provider.useFactory; - resolvedDeps = constructDependencies(provider.useFactory, provider.dependencies); + resolvedDeps = constructDependencies(provider.useFactory, provider.deps); } else { factoryFn = () => provider.useValue; resolvedDeps = _EMPTY_LIST; @@ -133,16 +135,15 @@ export function resolveReflectiveFactory(provider: Provider): ResolvedReflective * {@link Injector} internally only uses {@link ResolvedProvider}, {@link Provider} contains * convenience provider syntax. */ -export function resolveReflectiveProvider(provider: Provider): ResolvedReflectiveProvider { +function resolveReflectiveProvider(provider: NormalizedProvider): ResolvedReflectiveProvider { return new ResolvedReflectiveProvider_( - ReflectiveKey.get(provider.token), [resolveReflectiveFactory(provider)], provider.multi); + ReflectiveKey.get(provider.provide), [resolveReflectiveFactory(provider)], provider.multi); } /** * Resolve a list of Providers. */ -export function resolveReflectiveProviders( - providers: Array|Provider|{[k: string]: any}|any[]>): ResolvedReflectiveProvider[] { +export function resolveReflectiveProviders(providers: Provider[]): ResolvedReflectiveProvider[] { var normalized = _normalizeProviders(providers, []); var resolved = normalized.map(resolveReflectiveProvider); return MapWrapper.values( @@ -186,25 +187,17 @@ export function mergeResolvedReflectiveProviders( return normalizedProvidersMap; } -function _normalizeProviders( - providers: Array|Provider|{[k: string]: any}|ProviderBuilder|any[]>, - res: Provider[]): Provider[] { +function _normalizeProviders(providers: Provider[], res: Provider[]): Provider[] { providers.forEach(b => { if (b instanceof Type) { - res.push(provide(b, {useClass: b})); + res.push({provide: b, useClass: b}); - } else if (b instanceof Provider) { - res.push(b); - - } else if (isProviderLiteral(b)) { - res.push(createProvider(b)); + } else if (b && typeof b == 'object' && b.hasOwnProperty('provide')) { + res.push(b as NormalizedProvider); } else if (b instanceof Array) { _normalizeProviders(b, res); - } else if (b instanceof ProviderBuilder) { - throw new InvalidProviderError(b.token); - } else { throw new InvalidProviderError(b); } diff --git a/modules/@angular/core/src/linker/ng_module_factory_loader.ts b/modules/@angular/core/src/linker/ng_module_factory_loader.ts index 83e66a489d..f8c66b0eb6 100644 --- a/modules/@angular/core/src/linker/ng_module_factory_loader.ts +++ b/modules/@angular/core/src/linker/ng_module_factory_loader.ts @@ -9,7 +9,7 @@ import {NgModuleFactory} from './ng_module_factory'; /** - * Used to load ng moduled factories. + * Used to load ng module factories. * @experimental */ export abstract class NgModuleFactoryLoader { diff --git a/modules/@angular/core/src/platform_core_providers.ts b/modules/@angular/core/src/platform_core_providers.ts index 7cd7833601..9818270bfd 100644 --- a/modules/@angular/core/src/platform_core_providers.ts +++ b/modules/@angular/core/src/platform_core_providers.ts @@ -12,13 +12,12 @@ import {Provider} from './di'; import {Reflector, reflector} from './reflection/reflection'; import {ReflectorReader} from './reflection/reflector_reader'; import {TestabilityRegistry} from './testability/testability'; -import {Type} from './type'; function _reflector(): Reflector { return reflector; } -const _CORE_PLATFORM_PROVIDERS: Array|Provider|any[]> = [ +const _CORE_PLATFORM_PROVIDERS: Provider[] = [ PlatformRef_, {provide: PlatformRef, useExisting: PlatformRef_}, {provide: Reflector, useFactory: _reflector, deps: []}, {provide: ReflectorReader, useExisting: Reflector}, TestabilityRegistry, Console diff --git a/modules/@angular/core/test/change_detection/differs/iterable_differs_spec.ts b/modules/@angular/core/test/change_detection/differs/iterable_differs_spec.ts index 4b4d328ff4..d9c86f2192 100644 --- a/modules/@angular/core/test/change_detection/differs/iterable_differs_spec.ts +++ b/modules/@angular/core/test/change_detection/differs/iterable_differs_spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Injector, ReflectiveInjector, provide} from '@angular/core'; +import {Injector, ReflectiveInjector} from '@angular/core'; import {IterableDiffers} from '@angular/core/src/change_detection/differs/iterable_differs'; import {afterEach, beforeEach, ddescribe, describe, expect, iit, it, xit} from '@angular/core/testing/testing_internal'; diff --git a/modules/@angular/core/test/di/binding_spec.ts b/modules/@angular/core/test/di/binding_spec.ts deleted file mode 100644 index c999855916..0000000000 --- a/modules/@angular/core/test/di/binding_spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -import {bind, provide} from '@angular/core'; -import {beforeEach, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal'; - -export function main() { - describe('provider', () => { - - describe('type errors', () => { - - it('should throw when trying to create a class provider and not passing a class', () => { - expect(() => { - bind('foo').toClass(0); - }).toThrowError('Trying to create a class provider but "0" is not a class!'); - }); - - it('should throw when trying to create a factory provider and not passing a function', () => { - expect(() => { - bind('foo').toFactory(0); - }).toThrowError('Trying to create a factory provider but "0" is not a function!'); - }); - }); - }); -} diff --git a/modules/@angular/core/test/forward_ref_integration_spec.ts b/modules/@angular/core/test/forward_ref_integration_spec.ts index d59a3e7bdf..be14308b7d 100644 --- a/modules/@angular/core/test/forward_ref_integration_spec.ts +++ b/modules/@angular/core/test/forward_ref_integration_spec.ts @@ -7,7 +7,7 @@ */ import {NgFor} from '@angular/common'; -import {Component, ContentChildren, Directive, Inject, QueryList, asNativeElements, bind, forwardRef, provide, resolveForwardRef} from '@angular/core'; +import {Component, ContentChildren, Directive, Inject, QueryList, asNativeElements, forwardRef} from '@angular/core'; import {TestComponentBuilder} from '@angular/core/testing'; import {AsyncTestCompleter, beforeEach, ddescribe, describe, iit, inject, it, xit} from '@angular/core/testing/testing_internal'; import {expect} from '@angular/platform-browser/testing/matchers'; diff --git a/modules/@angular/core/test/linker/ng_module_integration_spec.ts b/modules/@angular/core/test/linker/ng_module_integration_spec.ts index 59c175c1e4..fe57c7e324 100644 --- a/modules/@angular/core/test/linker/ng_module_integration_spec.ts +++ b/modules/@angular/core/test/linker/ng_module_integration_spec.ts @@ -6,10 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {LowerCasePipe, NgIf} from '@angular/common'; -import {CompilerConfig, NgModuleResolver} from '@angular/compiler'; -import {MockNgModuleResolver} from '@angular/compiler/testing'; -import {ANALYZE_FOR_ENTRY_COMPONENTS, CUSTOM_ELEMENTS_SCHEMA, Compiler, Component, ComponentFactoryResolver, ComponentResolver, Directive, HostBinding, Inject, Injectable, Injector, Input, NgModule, NgModuleRef, Optional, Pipe, ReflectiveInjector, SelfMetadata, Type, forwardRef, provide} from '@angular/core'; +import {ANALYZE_FOR_ENTRY_COMPONENTS, CUSTOM_ELEMENTS_SCHEMA, Compiler, Component, ComponentFactoryResolver, ComponentResolver, Directive, HostBinding, Inject, Injectable, Injector, Input, NgModule, NgModuleRef, Optional, Pipe, ReflectiveInjector, SelfMetadata, Type, forwardRef} from '@angular/core'; import {Console} from '@angular/core/src/console'; import {ComponentFixture, TestBed} from '@angular/core/testing'; import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; @@ -720,7 +717,7 @@ function declareTests({useJit}: {useJit: boolean}) { }); it('should throw when no type and not @Inject (factory case)', () => { - expect(() => createInjector([provide('someToken', {useFactory: factoryFn})])) + expect(() => createInjector([{provide: 'someToken', useFactory: factoryFn}])) .toThrowError('Can\'t resolve all parameters for factoryFn: (?).'); }); @@ -734,7 +731,7 @@ function declareTests({useJit}: {useJit: boolean}) { }); it('should provide to a value', () => { - var injector = createInjector([provide(Engine, {useValue: 'fake engine'})]); + var injector = createInjector([{provide: Engine, useValue: 'fake engine'}]); var engine = injector.get(Engine); expect(engine).toEqual('fake engine'); @@ -744,7 +741,7 @@ function declareTests({useJit}: {useJit: boolean}) { function sportsCarFactory(e: Engine) { return new SportsCar(e); } var injector = - createInjector([Engine, provide(Car, {useFactory: sportsCarFactory, deps: [Engine]})]); + createInjector([Engine, {provide: Car, useFactory: sportsCarFactory, deps: [Engine]}]); var car = injector.get(Car); expect(car).toBeAnInstanceOf(SportsCar); @@ -752,15 +749,15 @@ function declareTests({useJit}: {useJit: boolean}) { }); it('should supporting provider to null', () => { - var injector = createInjector([provide(Engine, {useValue: null})]); + var injector = createInjector([{provide: Engine, useValue: null}]); var engine = injector.get(Engine); expect(engine).toBeNull(); }); it('should provide to an alias', () => { var injector = createInjector([ - Engine, provide(SportsCar, {useClass: SportsCar}), - provide(Car, {useExisting: SportsCar}) + Engine, {provide: SportsCar, useClass: SportsCar}, + {provide: Car, useExisting: SportsCar} ]); var car = injector.get(Car); @@ -771,8 +768,8 @@ function declareTests({useJit}: {useJit: boolean}) { it('should support multiProviders', () => { var injector = createInjector([ - Engine, provide(Car, {useClass: SportsCar, multi: true}), - provide(Car, {useClass: CarWithOptionalEngine, multi: true}) + Engine, {provide: Car, useClass: SportsCar, multi: true}, + {provide: Car, useClass: CarWithOptionalEngine, multi: true} ]); var cars = injector.get(Car); @@ -783,7 +780,7 @@ function declareTests({useJit}: {useJit: boolean}) { it('should support multiProviders that are created using useExisting', () => { var injector = createInjector( - [Engine, SportsCar, provide(Car, {useExisting: SportsCar, multi: true})]); + [Engine, SportsCar, {provide: Car, useExisting: SportsCar, multi: true}]); var cars = injector.get(Car); expect(cars.length).toEqual(1); @@ -791,22 +788,22 @@ function declareTests({useJit}: {useJit: boolean}) { }); it('should throw when the aliased provider does not exist', () => { - var injector = createInjector([provide('car', {useExisting: SportsCar})]); + var injector = createInjector([{provide: 'car', useExisting: SportsCar}]); var e = `No provider for ${stringify(SportsCar)}!`; expect(() => injector.get('car')).toThrowError(e); }); it('should handle forwardRef in useExisting', () => { var injector = createInjector([ - provide('originalEngine', {useClass: forwardRef(() => Engine)}), - provide('aliasedEngine', {useExisting: forwardRef(() => 'originalEngine')}) + {provide: 'originalEngine', useClass: forwardRef(() => Engine)}, + {provide: 'aliasedEngine', useExisting: forwardRef(() => 'originalEngine')} ]); expect(injector.get('aliasedEngine')).toBeAnInstanceOf(Engine); }); it('should support overriding factory dependencies', () => { var injector = createInjector( - [Engine, provide(Car, {useFactory: (e: Engine) => new SportsCar(e), deps: [Engine]})]); + [Engine, {provide: Car, useFactory: (e: Engine) => new SportsCar(e), deps: [Engine]}]); var car = injector.get(Car); expect(car).toBeAnInstanceOf(SportsCar); @@ -829,13 +826,13 @@ function declareTests({useJit}: {useJit: boolean}) { it('should use the last provider when there are multiple providers for same token', () => { var injector = createInjector( - [provide(Engine, {useClass: Engine}), provide(Engine, {useClass: TurboEngine})]); + [{provide: Engine, useClass: Engine}, {provide: Engine, useClass: TurboEngine}]); expect(injector.get(Engine)).toBeAnInstanceOf(TurboEngine); }); it('should use non-type tokens', () => { - var injector = createInjector([provide('token', {useValue: 'value'})]); + var injector = createInjector([{provide: 'token', useValue: 'value'}]); expect(injector.get('token')).toEqual('value'); }); @@ -859,12 +856,12 @@ function declareTests({useJit}: {useJit: boolean}) { }); it('should throw when trying to instantiate a cyclic dependency', () => { - expect(() => createInjector([Car, provide(Engine, {useClass: CyclicEngine})])) + expect(() => createInjector([Car, {provide: Engine, useClass: CyclicEngine}])) .toThrowError(/Cannot instantiate cyclic dependency! Car/g); }); it('should support null values', () => { - var injector = createInjector([provide('null', {useValue: null})]); + var injector = createInjector([{provide: 'null', useValue: null}]); expect(injector.get('null')).toBe(null); }); @@ -883,7 +880,7 @@ function declareTests({useJit}: {useJit: boolean}) { it('should not use the child providers when resolving the dependencies of a parent provider', () => { var parent = createInjector([Car, Engine]); - var child = createInjector([provide(Engine, {useClass: TurboEngine})], parent); + var child = createInjector([{provide: Engine, useClass: TurboEngine}], parent); var carFromChild = child.get(Car); expect(carFromChild.engine).toBeAnInstanceOf(Engine); @@ -891,7 +888,7 @@ function declareTests({useJit}: {useJit: boolean}) { it('should create new instance in a child injector', () => { var parent = createInjector([Engine]); - var child = createInjector([provide(Engine, {useClass: TurboEngine})], parent); + var child = createInjector([{provide: Engine, useClass: TurboEngine}], parent); var engineFromParent = parent.get(Engine); var engineFromChild = child.get(Engine); @@ -906,20 +903,22 @@ function declareTests({useJit}: {useJit: boolean}) { describe('@Self()', () => { it('should return a dependency from self', () => { var inj = createInjector([ - Engine, - provide( - Car, - {useFactory: (e: Engine) => new Car(e), deps: [[Engine, new SelfMetadata()]]}) + Engine, { + provide: Car, + useFactory: (e: Engine) => new Car(e), + deps: [[Engine, new SelfMetadata()]] + } ]); expect(inj.get(Car)).toBeAnInstanceOf(Car); }); it('should throw when not requested provider on self', () => { - expect(() => createInjector([provide(Car, { + expect(() => createInjector([{ + provide: Car, useFactory: (e: Engine) => new Car(e), deps: [[Engine, new SelfMetadata()]] - })])) + }])) .toThrowError(/No provider for Engine/g); }); }); @@ -929,8 +928,8 @@ function declareTests({useJit}: {useJit: boolean}) { var parent = createInjector([Engine]); var child = createInjector( [ - provide(Engine, {useClass: TurboEngine}), - provide(Car, {useFactory: (e: Engine) => new Car(e), deps: [Engine]}) + {provide: Engine, useClass: TurboEngine}, + {provide: Car, useFactory: (e: Engine) => new Car(e), deps: [Engine]} ], parent); diff --git a/modules/@angular/core/test/linker/view_injector_integration_spec.ts b/modules/@angular/core/test/linker/view_injector_integration_spec.ts index 8a11cf1d1e..d39f1e3940 100644 --- a/modules/@angular/core/test/linker/view_injector_integration_spec.ts +++ b/modules/@angular/core/test/linker/view_injector_integration_spec.ts @@ -7,7 +7,7 @@ */ import {NgFor, NgIf} from '@angular/common'; -import {Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, DebugElement, Directive, ElementRef, Host, Inject, InjectMetadata, Input, Optional, Pipe, PipeTransform, Self, SkipSelfMetadata, TemplateRef, Type, ViewContainerRef, ViewMetadata, forwardRef, provide} from '@angular/core'; +import {Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, DebugElement, Directive, ElementRef, Host, Inject, InjectMetadata, Input, Optional, Pipe, PipeTransform, Self, SkipSelfMetadata, TemplateRef, Type, ViewContainerRef, ViewMetadata, forwardRef} from '@angular/core'; import {ComponentFixture, TestComponentBuilder, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing'; import {beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; diff --git a/modules/@angular/core/testing/test_bed.ts b/modules/@angular/core/testing/test_bed.ts index 41a2a402e5..cdf3a65751 100644 --- a/modules/@angular/core/testing/test_bed.ts +++ b/modules/@angular/core/testing/test_bed.ts @@ -6,10 +6,10 @@ * found in the LICENSE file at https://angular.io/license */ -import {CompilerOptions, ComponentFactory, ComponentMetadataType, ComponentStillLoadingError, DirectiveMetadataType, Injector, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgModuleMetadataType, NgModuleRef, NgZone, OpaqueToken, PipeMetadataType, PlatformRef, Provider, ReflectiveInjector, SchemaMetadata, assertPlatform, createPlatform, getPlatform} from '../index'; +import {CompilerOptions, ComponentMetadataType, ComponentStillLoadingError, DirectiveMetadataType, Injector, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgModuleMetadataType, NgModuleRef, NgZone, OpaqueToken, PipeMetadataType, PlatformRef, Provider, SchemaMetadata} from '../index'; import {ListWrapper} from '../src/facade/collection'; import {BaseException} from '../src/facade/exceptions'; -import {FunctionWrapper, isPresent, stringify} from '../src/facade/lang'; +import {FunctionWrapper, stringify} from '../src/facade/lang'; import {Type} from '../src/type'; import {AsyncTestCompleter} from './async_test_completer'; import {ComponentFixture} from './component_fixture'; @@ -147,7 +147,7 @@ export class TestBed implements Injector { private _directiveOverrides: [Type, MetadataOverride][] = []; private _pipeOverrides: [Type, MetadataOverride][] = []; - private _providers: Array|Provider|any[]|any> = []; + private _providers: Provider[] = []; private _declarations: Array|any[]|any> = []; private _imports: Array|any[]|any> = []; private _schemas: Array = []; diff --git a/modules/@angular/core/testing/testing.ts b/modules/@angular/core/testing/testing.ts index 0c81b06ad2..c657b869bb 100644 --- a/modules/@angular/core/testing/testing.ts +++ b/modules/@angular/core/testing/testing.ts @@ -12,10 +12,8 @@ * allows tests to be asynchronous by either returning a promise or using a 'done' parameter. */ -import {SchemaMetadata} from '../index'; - import {resetFakeAsyncZone} from './fake_async'; -import {TestBed, TestModuleMetadata, getTestBed} from './test_bed'; +import {TestBed} from './test_bed'; declare var global: any; diff --git a/modules/@angular/core/testing/testing_internal.ts b/modules/@angular/core/testing/testing_internal.ts index 7c16a27d9a..835bbed2b2 100644 --- a/modules/@angular/core/testing/testing_internal.ts +++ b/modules/@angular/core/testing/testing_internal.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {provide} from '../index'; import {StringMapWrapper} from '../src/facade/collection'; import {Math, global, isFunction, isPromise} from '../src/facade/lang'; diff --git a/modules/@angular/docs/web_workers/web_workers.md b/modules/@angular/docs/web_workers/web_workers.md index 7e7cfc3ef2..a56664e950 100644 --- a/modules/@angular/docs/web_workers/web_workers.md +++ b/modules/@angular/docs/web_workers/web_workers.md @@ -45,7 +45,7 @@ import {WORKER_RENDER_PLATFORM, WORKER_RENDER_APPLICATION, WORKER_SCRIPT} from " import {platform} from "angular2/core"; platform([WORKER_RENDER_PLATFORM]) -.application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"}); +.application([WORKER_RENDER_APPLICATION, {provide: WORKER_SCRIPT, useValue: "loader.js"}; ``` ```JavaScript // loader.js @@ -125,7 +125,7 @@ class HelloWorld { main(List args, SendPort replyTo) { reflector.reflectionCapabilities = new ReflectionCapabilities(); - platform([WORKER_APP_PLATFORM, new Provider(RENDER_SEND_PORT, useValue: replyTo)]) + platform([WORKER_APP_PLATFORM, {provide: RENDER_SEND_PORT, useValue: replyTo}]) .application([WORKER_APP_APPLICATION]) .bootstrap(RootComponent); } @@ -219,7 +219,7 @@ import {WORKER_RENDER_PLATFORM, WORKER_RENDER_APPLICATION, WORKER_SCRIPT, Messag import {platform} from "angular2/core"; let appRef = platform([WORKER_RENDER_PLATFORM]) -.application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"}); +.application([WORKER_RENDER_APPLICATION, {provide: WORKER_SCRIPT, useValue: "loader.js"}; let bus = appRef.injector.get(MessageBus); bus.initChannel("My Custom Channel"); ``` @@ -243,7 +243,7 @@ import {WORKER_RENDER_PLATFORM, WORKER_RENDER_APPLICATION, WORKER_SCRIPT, Messag import {platform} from "angular2/core"; let appRef = platform([WORKER_RENDER_PLATFORM]) -.application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"}); +.application([WORKER_RENDER_APPLICATION, {provide: WORKER_SCRIPT, useValue: "loader.js"}; let bus = appRef.injector.get(MessageBus); bus.initChannel("My Custom Channel"); bus.to("My Custom Channel").emit("Hello from the UI"); @@ -335,7 +335,7 @@ during bootstrap like so: In TypeScript: ```TypeScript // index.ts, running on the UI side -import {platform, Provider, APP_INITIALIZER, Injector} from 'angular2/core'; +import {platform, APP_INITIALIZER, Injector} from 'angular2/core'; import { WORKER_RENDER_PLATFORM, WORKER_RENDER_APPLICATION_COMMON, @@ -345,18 +345,18 @@ import { var bus = new MyAwesomeMessageBus(); platform([WORKER_RENDER_PLATFORM]) -.application([WORKER_RENDER_APPLICATION_COMMON, new Provider(MessageBus, {useValue: bus}), - new Provider(APP_INITIALIZER, { +.application([WORKER_RENDER_APPLICATION_COMMON, {provide: MessageBus, useValue: bus}, + { provide: APP_INITIALIZER, useFactory: (injector) => () => initializeGenericWorkerRenderer(injector), deps: [Injector], multi: true - }) + } ]); ``` ```TypeScript // background_index.ts, running on the application side import {WORKER_APP_PLATFORM, genericWorkerAppProviders} from "angular2/platform/worker_app"; -import {NgZone, platform, Provider} from "angular/core"; +import {NgZone, platform} from "angular/core"; import {MyApp} from './app'; /** @@ -365,8 +365,8 @@ import {MyApp} from './app'; */ platform([WORKER_APP_PLATFORM_PROVIDERS]) -.application([WORKER_APP_APPLICATION_COMMON, new Provider(MessageBus, {useValue: bus}), -new Provider(APP_INITIALIZER, {useFactory: (zone, bus) => () => initAppThread(zone, bus), multi: true, deps: [NgZone, MessageBus]})]) +.application([WORKER_APP_APPLICATION_COMMON, {provide: MessageBus, useValue: bus}, +{provide: APP_INITIALIZER, useFactory: (zone, bus) => () => initAppThread(zone, bus), multi: true, deps: [NgZone, MessageBus]}]) .bootstrap(MyApp); function initAppThread(zone: NgZone, bus: MyAwesomeMessageBus): void{ @@ -406,7 +406,7 @@ import {WORKER_RENDER_PLATFORM, WORKER_RENDER_APPLICATION, WORKER_SCRIPT, Servic import {platform} from "angular2/core"; let appRef = platform([WORKER_RENDER_PLATFORM]) -.application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"}); +.application([WORKER_RENDER_APPLICATION, {provide: WORKER_SCRIPT, useValue: "loader.js"}; let injector = instance.injector; var broker = injector.get(ServiceMessageBrokerFactory).createMessageBroker("My Broker Channel"); diff --git a/modules/@angular/examples/compiler/ts/url_resolver/url_resolver.ts b/modules/@angular/examples/compiler/ts/url_resolver/url_resolver.ts index 04cc6eeb9d..eed80cb240 100644 --- a/modules/@angular/examples/compiler/ts/url_resolver/url_resolver.ts +++ b/modules/@angular/examples/compiler/ts/url_resolver/url_resolver.ts @@ -7,7 +7,6 @@ */ import {UrlResolver} from '@angular/compiler'; -import {provide} from '@angular/core'; import {bootstrap} from '@angular/platform-browser-dynamic'; var MyApp: any; diff --git a/modules/@angular/platform-browser-dynamic/index.ts b/modules/@angular/platform-browser-dynamic/index.ts index 9f514e7d03..882ffd60e0 100644 --- a/modules/@angular/platform-browser-dynamic/index.ts +++ b/modules/@angular/platform-browser-dynamic/index.ts @@ -7,7 +7,7 @@ */ import {XHR, analyzeAppProvidersForDeprecatedConfiguration, platformCoreDynamic} from '@angular/compiler'; -import {ApplicationRef, COMPILER_OPTIONS, CUSTOM_ELEMENTS_SCHEMA, CompilerFactory, CompilerOptions, ComponentRef, NgModule, PlatformRef, Type, createPlatformFactory} from '@angular/core'; +import {ApplicationRef, COMPILER_OPTIONS, CUSTOM_ELEMENTS_SCHEMA, CompilerFactory, CompilerOptions, ComponentRef, NgModule, PlatformRef, Provider, Type, createPlatformFactory} from '@angular/core'; import {BrowserModule, WORKER_SCRIPT, WorkerAppModule, platformWorkerUi} from '@angular/platform-browser'; import {Console} from './core_private'; @@ -15,11 +15,12 @@ import {INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS} from './src/platform_provid import {CachedXHR} from './src/xhr/xhr_cache'; import {XHRImpl} from './src/xhr/xhr_impl'; + + /** * @experimental */ -export const CACHED_TEMPLATE_PROVIDER: Array = - [{provide: XHR, useClass: CachedXHR}]; +export const CACHED_TEMPLATE_PROVIDER: Provider[] = [{provide: XHR, useClass: CachedXHR}]; /** * @experimental API related to bootstrapping are still under review. @@ -107,8 +108,7 @@ export const platformBrowserDynamic = createPlatformFactory( */ // Note: We are using typescript overloads here to have 2 function signatures! export function bootstrap( - appComponentType: Type, - customProviders?: Array): Promise> { + appComponentType: Type, customProviders?: Provider[]): Promise> { let compilerOptions: CompilerOptions; let declarations: any[] = []; let entryComponents: any[] = []; @@ -145,13 +145,13 @@ export function bootstrap( * @experimental */ export function bootstrapWorkerUi( - workerScriptUri: string, - customProviders: Array = []): Promise { + workerScriptUri: string, customProviders: Provider[] = []): Promise { // For now, just creates the worker ui platform... - return Promise.resolve(platformWorkerUi([{ + return Promise.resolve(platformWorkerUi(([{ provide: WORKER_SCRIPT, useValue: workerScriptUri, - }].concat(customProviders))); + }] as Provider[]) + .concat(customProviders))); } /** diff --git a/modules/@angular/platform-browser-dynamic/test/testing_public_browser_spec.ts b/modules/@angular/platform-browser-dynamic/test/testing_public_browser_spec.ts index 771a42cb02..573dca0abf 100644 --- a/modules/@angular/platform-browser-dynamic/test/testing_public_browser_spec.ts +++ b/modules/@angular/platform-browser-dynamic/test/testing_public_browser_spec.ts @@ -7,8 +7,8 @@ */ import {XHR} from '@angular/compiler'; -import {Component, bind} from '@angular/core'; -import {TestBed, async, fakeAsync, flushMicrotasks, inject, tick} from '@angular/core/testing'; +import {Component} from '@angular/core'; +import {TestBed, async, fakeAsync, inject, tick} from '@angular/core/testing'; import {XHRImpl} from '../src/xhr/xhr_impl'; diff --git a/modules/@angular/platform-browser/private_export.ts b/modules/@angular/platform-browser/private_export.ts index d250d72a28..1df8836424 100644 --- a/modules/@angular/platform-browser/private_export.ts +++ b/modules/@angular/platform-browser/private_export.ts @@ -6,6 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ +import {ClassProvider, ExistingProvider, FactoryProvider, TypeProvider, ValueProvider} from '@angular/core'; + import * as browser from './src/browser'; import * as ng_proble from './src/dom/debug/ng_probe'; import * as dom_adapter from './src/dom/dom_adapter'; diff --git a/modules/@angular/platform-browser/src/browser.ts b/modules/@angular/platform-browser/src/browser.ts index 30fe543148..d91a5718c2 100644 --- a/modules/@angular/platform-browser/src/browser.ts +++ b/modules/@angular/platform-browser/src/browser.ts @@ -7,7 +7,7 @@ */ import {CommonModule, PlatformLocation} from '@angular/common'; -import {ApplicationModule, ExceptionHandler, NgModule, NgModuleFactory, NgModuleRef, NgZone, OpaqueToken, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, RootRenderer, SanitizationService, Testability, assertPlatform, createPlatform, createPlatformFactory, getPlatform, isDevMode, platformCore} from '@angular/core'; +import {ApplicationModule, ExceptionHandler, NgModule, PLATFORM_INITIALIZER, PlatformRef, Provider, RootRenderer, SanitizationService, Testability, createPlatformFactory, platformCore} from '@angular/core'; import {wtfInit} from '../core_private'; import {AnimationDriver} from '../src/dom/animation_driver'; @@ -25,10 +25,9 @@ import {EVENT_MANAGER_PLUGINS, EventManager} from './dom/events/event_manager'; import {HAMMER_GESTURE_CONFIG, HammerGestureConfig, HammerGesturesPlugin} from './dom/events/hammer_gestures'; import {KeyEventsPlugin} from './dom/events/key_events'; import {DomSharedStylesHost, SharedStylesHost} from './dom/shared_styles_host'; -import {isBlank} from './facade/lang'; import {DomSanitizationService, DomSanitizationServiceImpl} from './security/dom_sanitization_service'; -export const INTERNAL_BROWSER_PLATFORM_PROVIDERS: Array = [ +export const INTERNAL_BROWSER_PLATFORM_PROVIDERS: Provider[] = [ {provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true}, {provide: PlatformLocation, useClass: BrowserPlatformLocation} ]; diff --git a/modules/@angular/platform-browser/src/worker_render.ts b/modules/@angular/platform-browser/src/worker_render.ts index 3cc37703aa..925154f402 100644 --- a/modules/@angular/platform-browser/src/worker_render.ts +++ b/modules/@angular/platform-browser/src/worker_render.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {BaseException, ExceptionHandler, Injectable, Injector, NgZone, OpaqueToken, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, RootRenderer, Testability, assertPlatform, createPlatform, createPlatformFactory, getPlatform, isDevMode, platformCore} from '@angular/core'; +import {BaseException, ExceptionHandler, Injectable, Injector, NgZone, OpaqueToken, PLATFORM_INITIALIZER, PlatformRef, Provider, RootRenderer, Testability, createPlatformFactory, isDevMode, platformCore} from '@angular/core'; import {wtfInit} from '../core_private'; @@ -22,7 +22,6 @@ import {EVENT_MANAGER_PLUGINS, EventManager} from './dom/events/event_manager'; import {HAMMER_GESTURE_CONFIG, HammerGestureConfig, HammerGesturesPlugin} from './dom/events/hammer_gestures'; import {KeyEventsPlugin} from './dom/events/key_events'; import {DomSharedStylesHost, SharedStylesHost} from './dom/shared_styles_host'; -import {isBlank} from './facade/lang'; import {ON_WEB_WORKER} from './web_workers/shared/api'; import {ClientMessageBrokerFactory, ClientMessageBrokerFactory_} from './web_workers/shared/client_message_broker'; import {MessageBus} from './web_workers/shared/message_bus'; @@ -70,7 +69,7 @@ export const WORKER_UI_STARTABLE_MESSAGING_SERVICE = /** * @experimental WebWorker support is currently experimental. */ -export const _WORKER_UI_PLATFORM_PROVIDERS: Array = [ +export const _WORKER_UI_PLATFORM_PROVIDERS: Provider[] = [ {provide: NgZone, useFactory: createNgZone, deps: []}, MessageBasedRenderer, {provide: WORKER_UI_STARTABLE_MESSAGING_SERVICE, useExisting: MessageBasedRenderer, multi: true}, @@ -88,7 +87,7 @@ export const _WORKER_UI_PLATFORM_PROVIDERS: Array = +const _TEST_BROWSER_PLATFORM_PROVIDERS: Provider[] = [{provide: PLATFORM_INITIALIZER, useValue: initBrowserTests, multi: true}]; /** diff --git a/modules/@angular/platform-server/src/server.ts b/modules/@angular/platform-server/src/server.ts index 7ce077cc9c..be858acf9e 100644 --- a/modules/@angular/platform-server/src/server.ts +++ b/modules/@angular/platform-server/src/server.ts @@ -63,4 +63,4 @@ export const platformServer = * @experimental */ export const platformDynamicServer = - createPlatformFactory(platformCoreDynamic, 'serverDynamic', INTERNAL_SERVER_PLATFORM_PROVIDERS); \ No newline at end of file + createPlatformFactory(platformCoreDynamic, 'serverDynamic', INTERNAL_SERVER_PLATFORM_PROVIDERS); diff --git a/modules/@angular/upgrade/src/upgrade_adapter.ts b/modules/@angular/upgrade/src/upgrade_adapter.ts index 497ca9a314..83ab164067 100644 --- a/modules/@angular/upgrade/src/upgrade_adapter.ts +++ b/modules/@angular/upgrade/src/upgrade_adapter.ts @@ -113,7 +113,7 @@ export class UpgradeAdapter { */ private ng1ComponentsToBeUpgraded: {[name: string]: UpgradeNg1ComponentAdapterBuilder} = {}; /* @internal */ - private providers: Array|Provider|any[]|any> = []; + private providers: Provider[] = []; // the ng2AppModule param should be required once the deprecated @Component.directives prop is // removed diff --git a/modules/benchpress/benchpress.ts b/modules/benchpress/benchpress.ts index b5fee64229..522f74983e 100644 --- a/modules/benchpress/benchpress.ts +++ b/modules/benchpress/benchpress.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {bind} from '@angular/core/src/di'; import {Options} from './common'; export * from './common'; diff --git a/modules/benchpress/common.ts b/modules/benchpress/common.ts index 7d834ea0f3..38cf4785ca 100644 --- a/modules/benchpress/common.ts +++ b/modules/benchpress/common.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -export {Injector, OpaqueToken, ReflectiveInjector, bind, provide} from '@angular/core/src/di'; +export {Injector, OpaqueToken, ReflectiveInjector} from '@angular/core/src/di'; export {Options} from './src/common_options'; export {MeasureValues} from './src/measure_values'; export {Metric} from './src/metric'; diff --git a/modules/benchpress/src/metric/user_metric.ts b/modules/benchpress/src/metric/user_metric.ts index 4ad9732712..aedf184bdf 100644 --- a/modules/benchpress/src/metric/user_metric.ts +++ b/modules/benchpress/src/metric/user_metric.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {OpaqueToken, Provider, bind} from '@angular/core'; +import {OpaqueToken, Provider} from '@angular/core'; import {StringMapWrapper} from '@angular/facade/src/collection'; import {isNumber} from '@angular/facade/src/lang'; @@ -68,7 +68,8 @@ export class UserMetric extends Metric { describe(): {[key: string]: any} { return this._userMetrics; } } -var _PROVIDERS = [bind(UserMetric) - .toFactory( - (userMetrics, wdAdapter) => new UserMetric(userMetrics, wdAdapter), - [Options.USER_METRICS, WebDriverAdapter])]; +var _PROVIDERS: Provider[] = [{ + provide: UserMetric, + useFactory: (userMetrics, wdAdapter) => new UserMetric(userMetrics, wdAdapter), + deps: [Options.USER_METRICS, WebDriverAdapter] +}]; diff --git a/modules/benchpress/test/metric/user_metric_spec.ts b/modules/benchpress/test/metric/user_metric_spec.ts index 1e50f376b9..d365d01299 100644 --- a/modules/benchpress/test/metric/user_metric_spec.ts +++ b/modules/benchpress/test/metric/user_metric_spec.ts @@ -6,11 +6,11 @@ * found in the LICENSE file at https://angular.io/license */ -import {ReflectiveInjector} from '@angular/core'; +import {Provider, ReflectiveInjector} from '@angular/core'; import {AsyncTestCompleter, afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal'; import {StringMapWrapper} from '@angular/facade/src/collection'; import {Json, isBlank, isPresent} from '@angular/facade/src/lang'; -import {Injector, Metric, MultiMetric, Options, PerfLogFeatures, PerflogMetric, UserMetric, WebDriverAdapter, WebDriverExtension, bind, provide} from 'benchpress/common'; +import {Injector, Metric, MultiMetric, Options, PerfLogFeatures, PerflogMetric, UserMetric, WebDriverAdapter, WebDriverExtension} from 'benchpress/common'; export function main() { var wdAdapter: MockDriverAdapter; @@ -26,10 +26,10 @@ export function main() { userMetrics = StringMapWrapper.create(); } wdAdapter = new MockDriverAdapter(); - var bindings = [ + var bindings: Provider[] = [ Options.DEFAULT_PROVIDERS, UserMetric.PROVIDERS, - bind(Options.USER_METRICS).toValue(userMetrics), - provide(WebDriverAdapter, {useValue: wdAdapter}) + {provide: Options.USER_METRICS, useValue: userMetrics}, + {provide: WebDriverAdapter, useValue: wdAdapter} ]; return ReflectiveInjector.resolveAndCreate(bindings).get(UserMetric); } diff --git a/tools/public_api_guard/common/index.d.ts b/tools/public_api_guard/common/index.d.ts index 17c97ff14d..afa239dbc0 100644 --- a/tools/public_api_guard/common/index.d.ts +++ b/tools/public_api_guard/common/index.d.ts @@ -9,7 +9,7 @@ export declare class AsyncPipe implements OnDestroy { } /** @experimental */ -export declare const COMMON_DIRECTIVES: any[]; +export declare const COMMON_DIRECTIVES: Provider[]; /** @experimental */ export declare const COMMON_PIPES: (typeof AsyncPipe | typeof SlicePipe | typeof I18nPluralPipe | typeof I18nSelectPipe)[]; diff --git a/tools/public_api_guard/core/index.d.ts b/tools/public_api_guard/core/index.d.ts index 0adb906e9f..e61becb56b 100644 --- a/tools/public_api_guard/core/index.d.ts +++ b/tools/public_api_guard/core/index.d.ts @@ -185,25 +185,6 @@ export declare class BaseException extends Error { toString(): string; } -/** @deprecated */ -export declare function bind(token: any): ProviderBuilder; - -/** @deprecated */ -export declare class Binding extends Provider { - /** @deprecated */ toAlias: any; - /** @deprecated */ toClass: Type; - /** @deprecated */ toFactory: Function; - /** @deprecated */ toValue: any; - constructor(token: any, {toClass, toValue, toAlias, toFactory, deps, multi}: { - toClass?: Type; - toValue?: any; - toAlias?: any; - toFactory: Function; - deps?: Object[]; - multi?: boolean; - }); -} - /** @stable */ export declare enum ChangeDetectionStrategy { OnPush = 0, @@ -229,6 +210,13 @@ export interface ClassDefinition { [x: string]: Type | Function | any[]; } +/** @stable */ +export interface ClassProvider { + multi?: boolean; + provide: any; + useClass: Type; +} + /** @stable */ export declare class CollectionChangeRecord { currentIndex: number; @@ -558,11 +546,26 @@ export declare class ExceptionHandler { static exceptionToString(exception: any, stackTrace?: any, reason?: string): string; } +/** @stable */ +export interface ExistingProvider { + multi?: boolean; + provide: any; + useExisting: any; +} + /** @stable */ export declare class ExpressionChangedAfterItHasBeenCheckedException extends BaseException { constructor(oldValue: any, currValue: any, context: any); } +/** @stable */ +export interface FactoryProvider { + deps: any[]; + multi?: boolean; + provide: any; + useFactory: Function; +} + /** @experimental */ export declare function forwardRef(forwardRefFn: ForwardRefFn): Type; @@ -967,44 +970,8 @@ export declare abstract class PlatformRef { abstract onDestroy(callback: () => void): void; } -/** @deprecated */ -export declare function provide(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}: { - useClass?: Type; - useValue?: any; - useExisting?: any; - useFactory?: Function; - deps?: Object[]; - multi?: boolean; -}): Provider; - -/** @deprecated */ -export declare class Provider { - dependencies: Object[]; - multi: boolean; - token: any; - useClass: Type; - useExisting: any; - useFactory: Function; - useValue: any; - constructor(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}: { - useClass?: Type; - useValue?: any; - useExisting?: any; - useFactory?: Function; - deps?: Object[]; - multi?: boolean; - }); -} - -/** @deprecated */ -export declare class ProviderBuilder { - token: any; - constructor(token: any); - toAlias(aliasToken: any): Provider; - toClass(type: Type): Provider; - toFactory(factory: Function, dependencies?: any[]): Provider; - toValue(value: any): Provider; -} +/** @stable */ +export declare type Provider = TypeProvider | ValueProvider | ClassProvider | ExistingProvider | FactoryProvider | any[]; /** @stable */ export declare class QueryList { @@ -1048,18 +1015,12 @@ export declare abstract class ReflectiveInjector implements Injector { createChildFromResolved(providers: ResolvedReflectiveProvider[]): ReflectiveInjector; abstract get(token: any, notFoundValue?: any): any; instantiateResolved(provider: ResolvedReflectiveProvider): any; - resolveAndCreateChild(providers: Array | Provider | { - [k: string]: any; - } | any[]>): ReflectiveInjector; - resolveAndInstantiate(provider: Type | Provider): any; + resolveAndCreateChild(providers: Provider[]): ReflectiveInjector; + resolveAndInstantiate(provider: Provider): any; /** @deprecated */ static fromResolvedBindings(providers: ResolvedReflectiveProvider[]): ReflectiveInjector; /** @experimental */ static fromResolvedProviders(providers: ResolvedReflectiveProvider[], parent?: Injector): ReflectiveInjector; - static resolve(providers: Array | Provider | { - [k: string]: any; - } | any[]>): ResolvedReflectiveProvider[]; - static resolveAndCreate(providers: Array | Provider | { - [k: string]: any; - } | any[]>, parent?: Injector): ReflectiveInjector; + static resolve(providers: Provider[]): ResolvedReflectiveProvider[]; + static resolveAndCreate(providers: Provider[], parent?: Injector): ReflectiveInjector; } /** @experimental */ @@ -1277,6 +1238,17 @@ export interface TypeDecorator { Class(obj: ClassDefinition): Type; } +/** @stable */ +export interface TypeProvider extends Type { +} + +/** @stable */ +export interface ValueProvider { + multi?: boolean; + provide: any; + useValue: any; +} + /** @stable */ export declare var ViewChild: ViewChildMetadataFactory; diff --git a/tools/public_api_guard/platform-browser-dynamic/index.d.ts b/tools/public_api_guard/platform-browser-dynamic/index.d.ts index d50a394239..d6ee42d97e 100644 --- a/tools/public_api_guard/platform-browser-dynamic/index.d.ts +++ b/tools/public_api_guard/platform-browser-dynamic/index.d.ts @@ -1,11 +1,11 @@ /** @deprecated */ -export declare function bootstrap(appComponentType: Type, customProviders?: Array): Promise>; +export declare function bootstrap(appComponentType: Type, customProviders?: Provider[]): Promise>; /** @experimental */ -export declare function bootstrapWorkerUi(workerScriptUri: string, customProviders?: Array): Promise; +export declare function bootstrapWorkerUi(workerScriptUri: string, customProviders?: Provider[]): Promise; /** @experimental */ -export declare const CACHED_TEMPLATE_PROVIDER: Array; +export declare const CACHED_TEMPLATE_PROVIDER: Provider[]; /** @experimental */ export declare const platformBrowserDynamic: (extraProviders?: any[]) => PlatformRef; diff --git a/tools/public_api_guard/platform-browser/index.d.ts b/tools/public_api_guard/platform-browser/index.d.ts index 0020bd1c97..f655752690 100644 --- a/tools/public_api_guard/platform-browser/index.d.ts +++ b/tools/public_api_guard/platform-browser/index.d.ts @@ -1,5 +1,5 @@ /** @experimental */ -export declare const _WORKER_UI_PLATFORM_PROVIDERS: Array; +export declare const _WORKER_UI_PLATFORM_PROVIDERS: Provider[]; /** @experimental */ export declare abstract class AnimationDriver {