From b0effe8e27dcd961eb697ac96960c91b3107715d Mon Sep 17 00:00:00 2001 From: vsavkin Date: Mon, 21 Sep 2015 14:19:03 -0700 Subject: [PATCH] docs(di): add docs to Injector Closes #4254 --- .../src/core/compiler/element_injector.ts | 6 +- modules/angular2/src/core/di.ts | 8 +- modules/angular2/src/core/di/binding.ts | 5 + modules/angular2/src/core/di/exceptions.ts | 12 + modules/angular2/src/core/di/injector.ts | 314 +++++++++++++----- modules/angular2/src/core/di/metadata.ts | 196 ++++++++--- modules/angular2/src/core/metadata/di.ts | 3 +- .../angular2/test/core/di/injector_spec.ts | 13 +- modules/angular2/test/public_api_spec.ts | 13 +- 9 files changed, 418 insertions(+), 152 deletions(-) diff --git a/modules/angular2/src/core/compiler/element_injector.ts b/modules/angular2/src/core/compiler/element_injector.ts index 50051c1bd6..d08231bd00 100644 --- a/modules/angular2/src/core/compiler/element_injector.ts +++ b/modules/angular2/src/core/compiler/element_injector.ts @@ -11,8 +11,6 @@ import {EventEmitter, ObservableWrapper} from 'angular2/src/core/facade/async'; import {ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/core/facade/collection'; import { Injector, - ProtoInjector, - Visibility, Key, Dependency, bind, @@ -24,8 +22,10 @@ import { resolveForwardRef, DependencyProvider } from 'angular2/src/core/di'; -import {UNDEFINED} from 'angular2/src/core/di/injector'; import { + UNDEFINED, + ProtoInjector, + Visibility, InjectorInlineStrategy, InjectorDynamicStrategy, BindingWithVisibility diff --git a/modules/angular2/src/core/di.ts b/modules/angular2/src/core/di.ts index 66cdf78a96..27f1e3ef73 100644 --- a/modules/angular2/src/core/di.ts +++ b/modules/angular2/src/core/di.ts @@ -18,13 +18,7 @@ export { export * from './di/decorators'; export {forwardRef, resolveForwardRef, ForwardRefFn} from './di/forward_ref'; -export { - Injector, - ProtoInjector, - BindingWithVisibility, - DependencyProvider, - Visibility -} from './di/injector'; +export {Injector, DependencyProvider} from './di/injector'; export { Binding, BindingBuilder, diff --git a/modules/angular2/src/core/di/binding.ts b/modules/angular2/src/core/di/binding.ts index 2ecd7f9828..021d861411 100644 --- a/modules/angular2/src/core/di/binding.ts +++ b/modules/angular2/src/core/di/binding.ts @@ -207,6 +207,11 @@ export class Binding { /** * Creates multiple bindings matching the same token (a multi-binding). * + * Multi-bindings are used for creating pluggable service, where the system comes + * with some default bindings, and the user can register additonal bindings. + * The combination of the default bindings and the additional bindings will be + * used to drive the behavior of the system. + * * ### Example * * ```typescript diff --git a/modules/angular2/src/core/di/exceptions.ts b/modules/angular2/src/core/di/exceptions.ts index 8983740da9..745bda927f 100644 --- a/modules/angular2/src/core/di/exceptions.ts +++ b/modules/angular2/src/core/di/exceptions.ts @@ -195,6 +195,18 @@ export class InvalidBindingError extends BaseException { * * expect(() => Injector.resolveAndCreate([A])).toThrowError(); * ``` + * + * This error is also thrown when the class not marked with {@link @Injectable} has parameter types. + * + * ```typescript + * class B {} + * + * class A { + * constructor(b:B) {} // no information about the parameter types of A is available at runtime. + * } + * + * expect(() => Injector.resolveAndCreate([A,B])).toThrowError(); + * ``` */ export class NoAnnotationError extends BaseException { constructor(typeOrFunc, params: any[][]) { diff --git a/modules/angular2/src/core/di/injector.ts b/modules/angular2/src/core/di/injector.ts index d0d05722b6..febda3b9b6 100644 --- a/modules/angular2/src/core/di/injector.ts +++ b/modules/angular2/src/core/di/injector.ts @@ -394,76 +394,103 @@ export interface DependencyProvider { } /** - * A dependency injection container used for resolving dependencies. + * A dependency injection container used for instantiating objects and resolving dependencies. * * An `Injector` is a replacement for a `new` operator, which can automatically resolve the * constructor dependencies. + * * In typical use, application code asks for the dependencies in the constructor and they are * resolved by the `Injector`. * - * ## Example: + * ### Example ([live demo](http://plnkr.co/edit/jzjec0?p=preview)) * - * Suppose that we want to inject an `Engine` into class `Car`, we would define it like this: + * The following example creates an `Injector` configured to create `Engine` and `Car`. * - * ```javascript + * ```typescript + * @Injectable() * class Engine { * } * + * @Injectable() * class Car { - * constructor(@Inject(Engine) engine) { - * } + * constructor(public engine:Engine) {} * } * + * var injector = Injector.resolveAndCreate([Car, Engine]); + * var car = injector.get(Car); + * expect(car instanceof Car).toBe(true); + * expect(car.engine instanceof Engine).toBe(true); * ``` * - * Next we need to write the code that creates and instantiates the `Injector`. We then ask for the - * `root` object, `Car`, so that the `Injector` can recursively build all of that object's - *dependencies. - * - * ```javascript - * main() { - * var injector = Injector.resolveAndCreate([Car, Engine]); - * - * // Get a reference to the `root` object, which will recursively instantiate the tree. - * var car = injector.get(Car); - * } - * ``` - * Notice that we don't use the `new` operator because we explicitly want to have the `Injector` + * Notice, we don't use the `new` operator because we explicitly want to have the `Injector` * resolve all of the object's dependencies automatically. */ export class Injector { /** - * Turns a list of binding definitions into an internal resolved list of resolved bindings. + * Turns an array of binding definitions into an array of resolved bindings. * - * A resolution is a process of flattening multiple nested lists and converting individual - * bindings into a list of {@link ResolvedBinding}s. The resolution can be cached by `resolve` - * for the {@link Injector} for performance-sensitive code. + * A resolution is a process of flattening multiple nested arrays and converting individual + * bindings into an array of {@link ResolvedBinding}s. * - * @param `bindings` can be a list of `Type`, {@link Binding}, {@link ResolvedBinding}, or a - * recursive list of more bindings. + * ### Example ([live demo](http://plnkr.co/edit/AiXTHi?p=preview)) * - * The returned list is sparse, indexed by `id` for the {@link Key}. It is generally not useful to - *application code - * other than for passing it to {@link Injector} functions that require resolved binding lists, - *such as - * `fromResolvedBindings` and `createChildFromResolved`. + * ```typescript + * @Injectable() + * class Engine { + * } + * + * @Injectable() + * class Car { + * constructor(public engine:Engine) {} + * } + * + * var bindings = Injector.resolve([Car, [[Engine]]]); + * + * expect(bindings.length).toEqual(2); + * + * expect(bindings[0] instanceof ResolvedBinding).toBe(true); + * expect(bindings[0].key.displayName).toBe("Car"); + * expect(bindings[0].dependencies.length).toEqual(1); + * expect(bindings[0].factory).toBeDefined(); + * + * expect(bindings[1].key.displayName).toBe("Engine"); + * }); + * ``` + * + * See {@link fromResolvedBindings} for more info. */ static resolve(bindings: Array): ResolvedBinding[] { return resolveBindings(bindings); } /** - * Resolves bindings and creates an injector based on those bindings. This function is slower than - * the corresponding `fromResolvedBindings` because it needs to resolve bindings first. See - *`resolve` - * for the {@link Injector}. + * Resolves an array of bindings and creates an injector from those bindings. * - * Prefer `fromResolvedBindings` in performance-critical code that creates lots of injectors. + * The passed-in bindings can be an array of `Type`, {@link Binding}, + * or a recursive array of more bindings. * - * @param `bindings` can be a list of `Type`, {@link Binding}, {@link ResolvedBinding}, or a - *recursive list of more - * bindings. - * @param `depProvider` + * The method also takes an optional {@link DependencyProvider}, which is used to + * resolve dependencies that cannot be expressed as bindings. + * + * ### Example ([live demo](http://plnkr.co/edit/ePOccA?p=preview)) + * + * ```typescript + * @Injectable() + * class Engine { + * } + * + * @Injectable() + * class Car { + * constructor(public engine:Engine) {} + * } + * + * var injector = Injector.resolveAndCreate([Car, Engine]); + * expect(injector.get(Car) instanceof Car).toBe(true); + * ``` + * + * This function is slower than the corresponding `fromResolvedBindings` + * because it needs to resolve the passed-in bindings first. + * See {@link resolve} and {@link fromResolvedBindings}. */ static resolveAndCreate(bindings: Array, depProvider: DependencyProvider = null): Injector { @@ -472,12 +499,29 @@ export class Injector { } /** - * Creates an injector from previously resolved bindings. This bypasses resolution and flattening. + * Creates an injector from previously resolved bindings. + * * This API is the recommended way to construct injectors in performance-sensitive parts. * - * @param `bindings` A sparse list of {@link ResolvedBinding}s. See `resolve` for the - * {@link Injector}. - * @param `depProvider` + * The method also takes an optional {@link DependencyProvider}, which is used to + * resolve dependencies that cannot be expressed as bindings. + * + * ### Example ([live demo](http://plnkr.co/edit/KrSMci?p=preview)) + * + * ```typescript + * @Injectable() + * class Engine { + * } + * + * @Injectable() + * class Car { + * constructor(public engine:Engine) {} + * } + * + * var bindings = Injector.resolve([Car, Engine]); + * var injector = Injector.fromResolvedBindings(bindings); + * expect(injector.get(Car) instanceof Car).toBe(true); + * ``` */ static fromResolvedBindings(bindings: ResolvedBinding[], depProvider: DependencyProvider = null): Injector { @@ -491,71 +535,128 @@ export class Injector { _isHost: boolean = false; _constructionCounter: number = 0; - constructor(public _proto: ProtoInjector, public _parent: Injector = null, + /** + * Private + */ + constructor(public _proto: any /* ProtoInjector */, public _parent: Injector = null, private _depProvider: DependencyProvider = null, private _debugContext: Function = null) { this._strategy = _proto._strategy.createInjectorStrategy(this); } /** - * Returns debug information about the injector. - * - * This information is included into exceptions thrown by the injector. + * @private */ debugContext(): any { return this._debugContext(); } /** - * Retrieves an instance from the injector. + * Retrieves an instance from the injector based on the provided token. + * Throws {@link NoBindingError} if not found. * - * @param `token`: usually the `Type` of an object. (Same as the token used while setting up a - *binding). - * @returns an instance represented by the token. Throws if not found. + * ### Example ([live demo](http://plnkr.co/edit/HeXSHg?p=preview)) + * + * ```typescript + * var injector = Injector.resolveAndCreate([ + * bind("validToken").toValue("Value") + * ]); + * expect(injector.get("validToken")).toEqual("Value"); + * expect(() => injector.get("invalidToken")).toThrowError(); + * ``` + * + * `Injector` returns itself when given `Injector` as a token. + * + * ```typescript + * var injector = Injector.resolveAndCreate([]); + * expect(injector.get(Injector)).toBe(injector); + * ``` */ get(token: any): any { return this._getByKey(Key.get(token), null, null, false, Visibility.PublicAndPrivate); } /** - * Retrieves an instance from the injector. + * Retrieves an instance from the injector based on the provided token. + * Returns null if not found. * - * @param `token`: usually a `Type`. (Same as the token used while setting up a binding). - * @returns an instance represented by the token. Returns `null` if not found. + * ### Example ([live demo](http://plnkr.co/edit/tpEbEy?p=preview)) + * + * ```typescript + * var injector = Injector.resolveAndCreate([ + * bind("validToken").toValue("Value") + * ]); + * expect(injector.getOptional("validToken")).toEqual("Value"); + * expect(injector.getOptional("invalidToken")).toBe(null); + * ``` + * + * `Injector` returns itself when given `Injector` as a token. + * + * ```typescript + * var injector = Injector.resolveAndCreate([]); + * expect(injector.getOptional(Injector)).toBe(injector); + * ``` */ getOptional(token: any): any { return this._getByKey(Key.get(token), null, null, true, Visibility.PublicAndPrivate); } /** - * Retrieves an instance from the injector. - * - * @param `index`: index of an instance. - * @returns an instance represented by the index. Throws if not found. + * @private */ getAt(index: number): any { return this._strategy.getObjAtIndex(index); } /** - * Direct parent of this injector. + * Parent of this injector. + * + * + * + * ### Example ([live demo](http://plnkr.co/edit/eosMGo?p=preview)) + * + * ```typescript + * var parent = Injector.resolveAndCreate([]); + * var child = parent.resolveAndCreateChild([]); + * expect(child.parent).toBe(parent); + * ``` */ get parent(): Injector { return this._parent; } /** + * @private * Internal. Do not use. - * * We return `any` not to export the InjectorStrategy type. */ get internalStrategy(): any { return this._strategy; } /** - * Creates a child injector and loads a new set of bindings into it. - * - * A resolution is a process of flattening multiple nested lists and converting individual - * bindings into a list of {@link ResolvedBinding}s. The resolution can be cached by `resolve` - * for the {@link Injector} for performance-sensitive code. - * - * @param `bindings` can be a list of `Type`, {@link Binding}, {@link ResolvedBinding}, or a - * recursive list of more bindings. - * @param `depProvider` - */ + * Resolves an array of bindings and creates a child injector from those bindings. + * + * + * + * The passed-in bindings can be an array of `Type`, {@link Binding}, + * or a recursive array of more bindings. + * + * The methods also takes an optional {@link DependencyProvider}, which is used to + * resolved dependencies that cannot be expressed as bindings. + * + * ### Example ([live demo](http://plnkr.co/edit/opB3T4?p=preview)) + * + * ```typescript + * class ParentBinding {} + * class ChildBinding {} + * + * var parent = Injector.resolveAndCreate([ParentBinding]); + * var child = parent.resolveAndCreateChild([ChildBinding]); + * + * expect(child.get(ParentBinding) instanceof ParentBinding).toBe(true); + * expect(child.get(ChildBinding) instanceof ChildBinding).toBe(true); + * expect(child.get(ParentBinding)).toBe(parent.get(ParentBinding)); + * ``` + * + * This function is slower than the corresponding `createChildFromResolved` + * because it needs to resolve the passed-in bindings first. + * See {@link resolve} and {@link createChildFromResolved}. + */ resolveAndCreateChild(bindings: Array, depProvider: DependencyProvider = null): Injector { var resolvedBindings = Injector.resolve(bindings); @@ -563,12 +664,32 @@ export class Injector { } /** - * Creates a child injector and loads a new set of {@link ResolvedBinding}s into it. + * Creates a child injector from previously resolved bindings. * - * @param `bindings`: A sparse list of {@link ResolvedBinding}s. - * See `resolve` for the {@link Injector}. - * @param `depProvider` - * @returns a new child {@link Injector}. + * + * + * This API is the recommended way to construct injectors in performance-sensitive parts. + * + * The methods also takes an optional {@link DependencyProvider}, which is used to + * resolved dependencies that cannot be expressed as bindings. + * + * ### Example ([live demo](http://plnkr.co/edit/VhyfjN?p=preview)) + * + * ```typescript + * class ParentBinding {} + * class ChildBinding {} + * + * var parentBindings = Injector.resolve([ParentBinding]); + * var childBindings = Injector.resolve([ChildBinding]); + * + * var parent = Injector.fromResolvedBindings(parentBindings); + * var child = parent.createChildFromResolved(childBindings); + * + * expect(child.get(ParentBinding) instanceof ParentBinding).toBe(true); + * expect(child.get(ChildBinding) instanceof ChildBinding).toBe(true); + * expect(child.get(ParentBinding)).toBe(parent.get(ParentBinding)); + * ``` */ createChildFromResolved(bindings: ResolvedBinding[], depProvider: DependencyProvider = null): Injector { @@ -582,8 +703,26 @@ export class Injector { /** * Resolves a binding and instantiates an object in the context of the injector. * - * @param `binding`: either a type or a binding. - * @returns an object created using binding. + * The created object does not get cached by the injector. + * + * ### Example ([live demo](http://plnkr.co/edit/yvVXoB?p=preview)) + * + * ```typescript + * @Injectable() + * class Engine { + * } + * + * @Injectable() + * class Car { + * constructor(public engine:Engine) {} + * } + * + * var injector = Injector.resolveAndCreate([Engine]); + * + * var car = injector.resolveAndInstantiate(Car); + * expect(car.engine).toBe(injector.get(Engine)); + * expect(car).not.toBe(injector.resolveAndInstantiate(Car)); + * ``` */ resolveAndInstantiate(binding: Type | Binding): any { return this.instantiateResolved(Injector.resolve([binding])[0]); @@ -592,8 +731,25 @@ export class Injector { /** * Instantiates an object using a resolved binding in the context of the injector. * - * @param `binding`: a resolved binding - * @returns an object created using binding. + * The created object does not get cached by the injector. + * + * ### Example ([live demo](http://plnkr.co/edit/ptCImQ?p=preview)) + * + * ```typescript + * @Injectable() + * class Engine { + * } + * + * @Injectable() + * class Car { + * constructor(public engine:Engine) {} + * } + * + * var injector = Injector.resolveAndCreate([Engine]); + * var carBinding = Injector.resolve([Car])[0]; + * var car = injector.instantiateResolved(carBinding); + * expect(car.engine).toBe(injector.get(Engine)); + * expect(car).not.toBe(injector.instantiateResolved(carBinding)); */ instantiateResolved(binding: ResolvedBinding): any { return this._instantiateBinding(binding, Visibility.PublicAndPrivate); diff --git a/modules/angular2/src/core/di/metadata.ts b/modules/angular2/src/core/di/metadata.ts index bb85d4c7fb..6ea1a62254 100644 --- a/modules/angular2/src/core/di/metadata.ts +++ b/modules/angular2/src/core/di/metadata.ts @@ -3,10 +3,41 @@ import {CONST, CONST_EXPR, stringify, isBlank, isPresent} from "angular2/src/cor /** * A parameter metadata that specifies a dependency. * - * ``` - * class AComponent { - * constructor(@Inject(MyService) aService:MyService) {} + * ### Example ([live demo](http://plnkr.co/edit/6uHYJK?p=preview)) + * + * ```typescript + * class Engine {} + * + * @Injectable() + * class Car { + * engine; + * constructor(@Inject("MyEngine") engine:Engine) { + * this.engine = engine; + * } * } + * + * var injector = Injector.resolveAndCreate([ + * bind("MyEngine").toClass(Engine), + * Car + * ]); + * + * expect(injector.get(Car).engine instanceof Engine).toBe(true); + * ``` + * + * When `@Inject()` is not present, {@link Injector} will use the type annotation of the parameter. + * + * ### Example + * + * ```typescript + * class Engine {} + * + * @Injectable() + * class Car { + * constructor(public engine: Engine) {} //same as constructor(@Inject(Engine) engine:Engine) + * } + * + * var injector = Injector.resolveAndCreate([Engine, Car]); + * expect(injector.get(Car).engine instanceof Engine).toBe(true); * ``` */ @CONST() @@ -19,12 +50,21 @@ export class InjectMetadata { * A parameter metadata that marks a dependency as optional. {@link Injector} provides `null` if * the dependency is not found. * - * ``` - * class AComponent { - * constructor(@Optional() aService:MyService) { - * this.aService = aService; + * ### Example ([live demo](http://plnkr.co/edit/AsryOm?p=preview)) + * + * ```typescript + * class Engine {} + * + * @Injectable() + * class Car { + * engine; + * constructor(@Optional() engine:Engine) { + * this.engine = engine; * } * } + * + * var injector = Injector.resolveAndCreate([Car]); + * expect(injector.get(Car).engine).toBeNull(); * ``` */ @CONST() @@ -64,16 +104,34 @@ export class DependencyMetadata { } /** - * A marker metadata that marks a class as available to `Injector` for creation. Used by tooling - * for generating constructor stubs. + * A marker metadata that marks a class as available to {@link Injector} for creation. * - * ``` + * ### Example ([live demo](http://plnkr.co/edit/Wk4DMQ?p=preview)) + * + * ```typescript + * @Injectable() + * class UsefulService {} + * + * @Injectable() * class NeedsService { - * constructor(svc:UsefulService) {} + * constructor(public service:UsefulService) {} * } * - * @Injectable + * var injector = Injector.resolveAndCreate([NeedsService, UsefulService]); + * expect(injector.get(NeedsService).service instanceof UsefulService).toBe(true); + * ``` + * {@link Injector} will throw {@link NoAnnotationError} when trying to instantiate a class that + * does not have `@Injectable` marker, as shown in the example below. + * + * ```typescript * class UsefulService {} + * + * class NeedsService { + * constructor(public service:UsefulService) {} + * } + * + * var injector = Injector.resolveAndCreate([NeedsService, UsefulService]); + * expect(() => injector.get(NeedsService)).toThrowError(); * ``` */ @CONST() @@ -82,21 +140,32 @@ export class InjectableMetadata { } /** - * Specifies that an injector should retrieve a dependency from itself. + * Specifies that an {@link Injector} should retrieve a dependency only from itself. * - * ## Example + * ### Example ([live demo](http://plnkr.co/edit/NeagAg?p=preview)) * - * ``` + * ```typescript * class Dependency { * } * + * @Injectable() * class NeedsDependency { - * constructor(public @Self() dependency:Dependency) {} + * dependency; + + * dependency; + * constructor(@Self() dependency:Dependency) { + * this.dependency = dependency; + * } * } * * var inj = Injector.resolveAndCreate([Dependency, NeedsDependency]); * var nd = inj.get(NeedsDependency); - * expect(nd.dependency).toBeAnInstanceOf(Dependency); + * + * expect(nd.dependency instanceof Dependency).toBe(true); + * + * var inj = Injector.resolveAndCreate([Dependency]); + * var child = inj.resolveAndCreateChild([NeedsDependency]); + * expect(() => child.get(NeedsDependency)).toThrowError(); * ``` */ @CONST() @@ -107,28 +176,26 @@ export class SelfMetadata { /** * Specifies that the dependency resolution should start from the parent injector. * - * ## Example + * ### Example ([live demo](http://plnkr.co/edit/Wchdzb?p=preview)) * - * - * ``` - * class Service {} - * - * class ParentService implements Service { + * ```typescript + * class Dependency { * } * - * class ChildService implements Service { - * constructor(public @SkipSelf() parentService:Service) {} + * @Injectable() + * class NeedsDependency { + * dependency; + * constructor(@SkipSelf() dependency:Dependency) { + * this.dependency = dependency; + * } * } * - * var parent = Injector.resolveAndCreate([ - * bind(Service).toClass(ParentService) - * ]); - * var child = parent.resolveAndCreateChild([ - * bind(Service).toClass(ChildSerice) - * ]); - * var s = child.get(Service); - * expect(s).toBeAnInstanceOf(ChildService); - * expect(s.parentService).toBeAnInstanceOf(ParentService); + * var parent = Injector.resolveAndCreate([Dependency]); + * var child = parent.resolveAndCreateChild([NeedsDependency]); + * expect(child.get(NeedsDependency).dependency instanceof Depedency).toBe(true); + * + * var inj = Injector.resolveAndCreate([Dependency, NeedsDependency]); + * expect(() => inj.get(NeedsDependency)).toThrowError(); * ``` */ @CONST() @@ -140,24 +207,59 @@ export class SkipSelfMetadata { * Specifies that an injector should retrieve a dependency from any injector until reaching the * closest host. * - * ## Example + * In Angular, a component element is automatically declared as a host for all the injectors in + * its view. * - * ``` - * class Dependency { + * ### Example ([live demo](http://plnkr.co/edit/GX79pV?p=preview)) + * + * In the following example `App` contains `ParentCmp`, which contains `ChildDirective`. + * So `ParentCmp` is the host of `ChildDirective`. + * + * `ChildDirective` depends on two services: `HostService` and `OtherService`. + * `HostService` is defined at `ParentCmp`, and `OtherService` is defined at `App`. + * + *```typescript + * class OtherService {} + * class HostService {} + * + * @Directive({ + * selector: 'child-directive' + * }) + * class ChildDirective { + * constructor(@Optional() @Host() os:OtherService, @Optional() @Host() hs:HostService){ + * console.log("os is null", os); + * console.log("hs is NOT null", hs); + * } * } * - * class NeedsDependency { - * constructor(public @Host() dependency:Dependency) {} + * @Component({ + * selector: 'parent-cmp', + * bindings: [HostService] + * }) + * @View({ + * template: ` + * Dir: + * `, + * directives: [ChildDirective] + * }) + * class ParentCmp { * } * - * var parent = Injector.resolveAndCreate([ - * bind(Dependency).toClass(HostDependency) - * ]); - * var child = parent.resolveAndCreateChild([]); - * var grandChild = child.resolveAndCreateChild([NeedsDependency, Depedency]); - * var nd = grandChild.get(NeedsDependency); - * expect(nd.dependency).toBeAnInstanceOf(HostDependency); - * ``` + * @Component({ + * selector: 'app', + * bindings: [OtherService] + * }) + * @View({ + * template: ` + * Parent: + * `, + * directives: [ParentCmp] + * }) + * class App { + * } + * + * bootstrap(App); + *``` */ @CONST() export class HostMetadata { diff --git a/modules/angular2/src/core/metadata/di.ts b/modules/angular2/src/core/metadata/di.ts index 13fdd8a258..2bfc595fe2 100644 --- a/modules/angular2/src/core/metadata/di.ts +++ b/modules/angular2/src/core/metadata/di.ts @@ -6,7 +6,8 @@ import { StringWrapper, isString } from 'angular2/src/core/facade/lang'; -import {DependencyMetadata, resolveForwardRef} from 'angular2/src/core/di'; +import {resolveForwardRef} from 'angular2/src/core/di'; +import {DependencyMetadata} from 'angular2/src/core/di/metadata'; /** * Specifies that a constant attribute value should be injected. diff --git a/modules/angular2/test/core/di/injector_spec.ts b/modules/angular2/test/core/di/injector_spec.ts index 09e349c6e3..6d773229d4 100644 --- a/modules/angular2/test/core/di/injector_spec.ts +++ b/modules/angular2/test/core/di/injector_spec.ts @@ -4,12 +4,10 @@ import {describe, ddescribe, it, iit, expect, beforeEach} from 'angular2/test_li import {SpyDependencyProvider} from '../spies'; import { Injector, - ProtoInjector, bind, ResolvedBinding, Key, forwardRef, - DependencyMetadata, Injectable, InjectMetadata, SelfMetadata, @@ -17,12 +15,17 @@ import { SkipSelfMetadata, Optional, Inject, - BindingWithVisibility, - Visibility, Binding } from 'angular2/core'; +import {DependencyMetadata} from 'angular2/src/core/di/metadata'; -import {InjectorInlineStrategy, InjectorDynamicStrategy} from 'angular2/src/core/di/injector'; +import { + InjectorInlineStrategy, + InjectorDynamicStrategy, + ProtoInjector, + BindingWithVisibility, + Visibility +} from 'angular2/src/core/di/injector'; class CustomDependencyMetadata extends DependencyMetadata {} diff --git a/modules/angular2/test/public_api_spec.ts b/modules/angular2/test/public_api_spec.ts index ee9828f3d2..77d25478d8 100644 --- a/modules/angular2/test/public_api_spec.ts +++ b/modules/angular2/test/public_api_spec.ts @@ -115,9 +115,6 @@ const NG_API = [ 'BindingBuilder.toFactory', 'BindingBuilder.toValue', - 'BindingWithVisibility', - 'BindingWithVisibility.getKeyId', - 'By', // TODO: not sure 'By.all', 'By.css', @@ -351,6 +348,9 @@ const NG_API = [ 'DebugElement.queryAll', 'DebugElement.triggerEventHandler', + 'DependencyMetadata', + 'DependencyMetadata.token', + 'DecimalPipe', 'DecimalPipe.constructor', 'DecimalPipe.transform', @@ -370,8 +370,6 @@ const NG_API = [ 'Dependency', 'Dependency.fromKey', - 'DependencyMetadata', - 'DependencyMetadata.token', 'Directive', 'Directive.constructor', @@ -750,9 +748,6 @@ const NG_API = [ 'PropertyMetadata', - 'ProtoInjector', - 'ProtoInjector.getBindingAtIndex', - 'ProtoViewRef', 'Query', @@ -979,8 +974,6 @@ const NG_API = [ 'ViewRef.renderFragment', 'ViewRef.setLocal', - 'Visibility', - 'WrappedException', 'WrappedException.captureStackTrace', 'WrappedException.constructor',