
This matches how DefinitelyTyped tests it, so we are one step closer to publishing the same file we generate. See #3195
201 lines
4.9 KiB
TypeScript
201 lines
4.9 KiB
TypeScript
import {CONST, CONST_EXPR, stringify, isBlank, isPresent} from "angular2/src/facade/lang";
|
|
|
|
/**
|
|
* A parameter metadata that specifies a dependency.
|
|
*
|
|
* ```
|
|
* class AComponent {
|
|
* constructor(@Inject(MyService) aService:MyService) {}
|
|
* }
|
|
* ```
|
|
*/
|
|
|
|
@CONST()
|
|
export class InjectMetadata {
|
|
constructor(public token) {}
|
|
toString(): string { return `@Inject(${stringify(this.token)})`; }
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
* }
|
|
* }
|
|
* ```
|
|
*/
|
|
@CONST()
|
|
export class OptionalMetadata {
|
|
toString(): string { return `@Optional()`; }
|
|
}
|
|
|
|
/**
|
|
* `DependencyMetadata is used by the framework to extend DI.
|
|
*
|
|
* Only metadata implementing `DependencyMetadata` are added to the list of dependency
|
|
* properties.
|
|
*
|
|
* For example:
|
|
*
|
|
* ```
|
|
* class Exclude extends DependencyMetadata {}
|
|
* class NotDependencyProperty {}
|
|
*
|
|
* class AComponent {
|
|
* constructor(@Exclude @NotDependencyProperty aService:AService) {}
|
|
* }
|
|
* ```
|
|
*
|
|
* will create the following dependency:
|
|
*
|
|
* ```
|
|
* new Dependency(Key.get(AService), [new Exclude()])
|
|
* ```
|
|
*
|
|
* The framework can use `new Exclude()` to handle the `aService` dependency
|
|
* in a specific way.
|
|
*/
|
|
@CONST()
|
|
export class DependencyMetadata {
|
|
get token() { return null; }
|
|
}
|
|
|
|
/**
|
|
* A marker metadata that marks a class as available to `Injector` for creation. Used by tooling
|
|
* for generating constructor stubs.
|
|
*
|
|
* ```
|
|
* class NeedsService {
|
|
* constructor(svc:UsefulService) {}
|
|
* }
|
|
*
|
|
* @Injectable
|
|
* class UsefulService {}
|
|
* ```
|
|
*/
|
|
@CONST()
|
|
export class InjectableMetadata {
|
|
constructor() {}
|
|
}
|
|
|
|
/**
|
|
* Specifies how injector should resolve a dependency.
|
|
*
|
|
* See {@link Self}, {@link Ancestor}, {@link Unbounded}.
|
|
*/
|
|
@CONST()
|
|
export class VisibilityMetadata {
|
|
constructor(public crossBoundaries: boolean, public _includeSelf: boolean) {}
|
|
|
|
get includeSelf(): boolean { return isBlank(this._includeSelf) ? false : this._includeSelf; }
|
|
|
|
toString(): string {
|
|
return `@Visibility(crossBoundaries: ${this.crossBoundaries}, includeSelf: ${this.includeSelf}})`;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Specifies that an injector should retrieve a dependency from itself.
|
|
*
|
|
* ## Example
|
|
*
|
|
* ```
|
|
* class Dependency {
|
|
* }
|
|
*
|
|
* class NeedsDependency {
|
|
* constructor(public @Self() dependency:Dependency) {}
|
|
* }
|
|
*
|
|
* var inj = Injector.resolveAndCreate([Dependency, NeedsDependency]);
|
|
* var nd = inj.get(NeedsDependency);
|
|
* expect(nd.dependency).toBeAnInstanceOf(Dependency);
|
|
* ```
|
|
*/
|
|
@CONST()
|
|
export class SelfMetadata extends VisibilityMetadata {
|
|
constructor() { super(false, true); }
|
|
toString(): string { return `@Self()`; }
|
|
}
|
|
|
|
/**
|
|
* Specifies that an injector should retrieve a dependency from any ancestor from the same boundary.
|
|
*
|
|
* ## Example
|
|
*
|
|
* ```
|
|
* class Dependency {
|
|
* }
|
|
*
|
|
* class NeedsDependency {
|
|
* constructor(public @Ancestor() dependency:Dependency) {}
|
|
* }
|
|
*
|
|
* var parent = Injector.resolveAndCreate([
|
|
* bind(Dependency).toClass(AncestorDependency)
|
|
* ]);
|
|
* var child = parent.resolveAndCreateChild([]);
|
|
* var grandChild = child.resolveAndCreateChild([NeedsDependency, Depedency]);
|
|
* var nd = grandChild.get(NeedsDependency);
|
|
* expect(nd.dependency).toBeAnInstanceOf(AncestorDependency);
|
|
* ```
|
|
*
|
|
* You can make an injector to retrive a dependency either from itself or its ancestor by setting
|
|
* self to true.
|
|
*
|
|
* ```
|
|
* class NeedsDependency {
|
|
* constructor(public @Ancestor({self:true}) dependency:Dependency) {}
|
|
* }
|
|
* ```
|
|
*/
|
|
@CONST()
|
|
export class AncestorMetadata extends VisibilityMetadata {
|
|
constructor({self}: {self?: boolean} = {}) { super(false, self); }
|
|
toString(): string { return `@Ancestor(self: ${this.includeSelf}})`; }
|
|
}
|
|
|
|
/**
|
|
* Specifies that an injector should retrieve a dependency from any ancestor, crossing boundaries.
|
|
*
|
|
* ## Example
|
|
*
|
|
* ```
|
|
* class Dependency {
|
|
* }
|
|
*
|
|
* class NeedsDependency {
|
|
* constructor(public @Ancestor() dependency:Dependency) {}
|
|
* }
|
|
*
|
|
* var parent = Injector.resolveAndCreate([
|
|
* bind(Dependency).toClass(AncestorDependency)
|
|
* ]);
|
|
* var child = parent.resolveAndCreateChild([]);
|
|
* var grandChild = child.resolveAndCreateChild([NeedsDependency, Depedency]);
|
|
* var nd = grandChild.get(NeedsDependency);
|
|
* expect(nd.dependency).toBeAnInstanceOf(AncestorDependency);
|
|
* ```
|
|
*
|
|
* You can make an injector to retrive a dependency either from itself or its ancestor by setting
|
|
* self to true.
|
|
*
|
|
* ```
|
|
* class NeedsDependency {
|
|
* constructor(public @Ancestor({self:true}) dependency:Dependency) {}
|
|
* }
|
|
* ```
|
|
*/
|
|
@CONST()
|
|
export class UnboundedMetadata extends VisibilityMetadata {
|
|
constructor({self}: {self?: boolean} = {}) { super(true, self); }
|
|
toString(): string { return `@Unbounded(self: ${this.includeSelf}})`; }
|
|
}
|
|
|
|
export const DEFAULT_VISIBILITY: VisibilityMetadata =
|
|
CONST_EXPR(new UnboundedMetadata({self: true}));
|