1- import { Type , isBlank , isPresent } from 'angular2/src/facade/lang' ;
1+ import { Type , isBlank , isPresent , CONST } from 'angular2/src/facade/lang' ;
22import { List , MapWrapper , ListWrapper } from 'angular2/src/facade/collection' ;
33import { reflector } from 'angular2/src/reflection/reflection' ;
44import { Key } from './key' ;
55import { Inject , InjectLazy , InjectPromise , Optional , DependencyAnnotation } from './annotations' ;
6- import { NoAnnotationError } from './exceptions' ;
6+ import { NoAnnotationError , InvalidBindingError } from './exceptions' ;
77
88export class Dependency {
99 key :Key ;
1010 asPromise:boolean ;
1111 lazy:boolean ;
1212 optional:boolean ;
1313 properties:List ;
14+
1415 constructor ( key :Key , asPromise :boolean , lazy :boolean , optional :boolean , properties :List ) {
1516 this . key = key ;
1617 this . asPromise = asPromise ;
@@ -24,80 +25,155 @@ export class Dependency {
2425 }
2526}
2627
28+ var _EMPTY_LIST = [ ] ; // TODO: make const when supported
29+
30+ /**
31+ * Declaration of a dependency binding.
32+ */
2733export class Binding {
34+ token ;
35+ toClass :Type ;
36+ toValue ;
37+ toAlias ;
38+ toFactory :Function ;
39+ toAsyncFactory :Function ;
40+ dependencies :List ;
41+
42+ @CONST ( )
43+ constructor (
44+ token ,
45+ {
46+ toClass,
47+ toValue,
48+ toAlias,
49+ toFactory,
50+ toAsyncFactory,
51+ deps
52+ } ) {
53+ this . token = token ;
54+ this . toClass = toClass ;
55+ this . toValue = toValue ;
56+ this . toAlias = toAlias ;
57+ this . toFactory = toFactory ;
58+ this . toAsyncFactory = toAsyncFactory ;
59+ this . dependencies = deps ;
60+ }
61+
62+ resolve ( ) : ResolvedBinding {
63+ var factoryFn :Function ;
64+ var resolvedDeps ;
65+ var isAsync = false ;
66+ if ( isPresent ( this . toClass ) ) {
67+ factoryFn = reflector . factory ( this . toClass ) ;
68+ resolvedDeps = _dependenciesFor ( this . toClass ) ;
69+ } else if ( isPresent ( this . toAlias ) ) {
70+ factoryFn = ( aliasInstance ) => aliasInstance ;
71+ resolvedDeps = [ Dependency . fromKey ( Key . get ( this . toAlias ) ) ] ;
72+ } else if ( isPresent ( this . toFactory ) ) {
73+ factoryFn = this . toFactory ;
74+ resolvedDeps = _constructDependencies ( this . toFactory , this . dependencies ) ;
75+ } else if ( isPresent ( this . toAsyncFactory ) ) {
76+ factoryFn = this . toAsyncFactory ;
77+ resolvedDeps = _constructDependencies ( this . toAsyncFactory , this . dependencies ) ;
78+ isAsync = true ;
79+ } else {
80+ factoryFn = ( ) => this . toValue ;
81+ resolvedDeps = _EMPTY_LIST ;
82+ }
83+
84+ return new ResolvedBinding (
85+ Key . get ( this . token ) ,
86+ factoryFn ,
87+ resolvedDeps ,
88+ isAsync
89+ ) ;
90+ }
91+
92+ static resolveAll ( bindings :List ) : List {
93+ var resolvedList = ListWrapper . createFixedSize ( bindings . length ) ;
94+ for ( var i = 0 ; i < bindings . length ; i ++ ) {
95+ var unresolved = bindings [ i ] ;
96+ var resolved ;
97+ if ( unresolved instanceof Type ) {
98+ resolved = bind ( unresolved ) . toClass ( unresolved ) . resolve ( ) ;
99+ } else if ( unresolved instanceof Binding ) {
100+ resolved = unresolved . resolve ( ) ;
101+ } else if ( unresolved instanceof List ) {
102+ resolved = Binding . resolveAll ( unresolved ) ;
103+ } else if ( unresolved instanceof BindingBuilder ) {
104+ throw new InvalidBindingError ( unresolved . token ) ;
105+ } else {
106+ throw new InvalidBindingError ( unresolved ) ;
107+ }
108+ resolvedList [ i ] = resolved ;
109+ }
110+ return resolvedList ;
111+ }
112+ }
113+
114+ /// Dependency binding with resolved keys and dependencies.
115+ export class ResolvedBinding {
28116 key :Key ;
29117 factory:Function ;
30- dependencies:List ;
118+ dependencies:List < Dependency > ;
31119 providedAsPromise:boolean ;
32120
33- constructor ( key :Key , factory :Function , dependencies :List , providedAsPromise :boolean ) {
121+ constructor ( key :Key , factory :Function , dependencies :List < Dependency > , providedAsPromise :boolean ) {
34122 this . key = key ;
35123 this . factory = factory ;
36124 this . dependencies = dependencies ;
37125 this . providedAsPromise = providedAsPromise ;
38126 }
39127}
40128
129+ /**
130+ * Provides fluent API for imperative construction of [Binding] objects.
131+ */
41132export function bind ( token ) :BindingBuilder {
42133 return new BindingBuilder ( token ) ;
43134}
44135
136+ /**
137+ * Helper class for [bind] function.
138+ */
45139export class BindingBuilder {
46140 token ;
141+
47142 constructor ( token ) {
48143 this . token = token ;
49144 }
50145
51146 toClass ( type :Type ) :Binding {
52- return new Binding (
53- Key . get ( this . token ) ,
54- reflector . factory ( type ) ,
55- _dependenciesFor ( type ) ,
56- false
57- ) ;
147+ return new Binding ( this . token , { toClass : type } ) ;
58148 }
59149
60150 toValue ( value ) :Binding {
61- return new Binding (
62- Key . get ( this . token ) ,
63- ( ) => value ,
64- [ ] ,
65- false
66- ) ;
151+ return new Binding ( this . token , { toValue : value } ) ;
67152 }
68153
69154 toAlias ( aliasToken ) :Binding {
70- return new Binding (
71- Key . get ( this . token ) ,
72- ( aliasInstance ) => aliasInstance ,
73- [ Dependency . fromKey ( Key . get ( aliasToken ) ) ] ,
74- false
75- ) ;
155+ return new Binding ( this . token , { toAlias : aliasToken } ) ;
76156 }
77157
78158 toFactory ( factoryFunction :Function , dependencies :List = null ) :Binding {
79- return new Binding (
80- Key . get ( this . token ) ,
81- factoryFunction ,
82- this . _constructDependencies ( factoryFunction , dependencies ) ,
83- false
84- ) ;
159+ return new Binding ( this . token , {
160+ toFactory : factoryFunction ,
161+ deps : dependencies
162+ } ) ;
85163 }
86164
87165 toAsyncFactory ( factoryFunction :Function , dependencies :List = null ) :Binding {
88- return new Binding (
89- Key . get ( this . token ) ,
90- factoryFunction ,
91- this . _constructDependencies ( factoryFunction , dependencies ) ,
92- true
93- ) ;
166+ return new Binding ( this . token , {
167+ toAsyncFactory : factoryFunction ,
168+ deps : dependencies
169+ } ) ;
94170 }
171+ }
95172
96- _constructDependencies ( factoryFunction :Function , dependencies :List ) {
97- return isBlank ( dependencies ) ?
98- _dependenciesFor ( factoryFunction ) :
99- ListWrapper . map ( dependencies , ( t ) => Dependency . fromKey ( Key . get ( t ) ) ) ;
100- }
173+ function _constructDependencies ( factoryFunction :Function , dependencies :List ) {
174+ return isBlank ( dependencies ) ?
175+ _dependenciesFor ( factoryFunction ) :
176+ ListWrapper . map ( dependencies , ( t ) => Dependency . fromKey ( Key . get ( t ) ) ) ;
101177}
102178
103179function _dependenciesFor ( typeOrFunc ) :List {
0 commit comments