OLD | NEW |
| (Empty) |
1 part of di; | |
2 | |
3 typedef dynamic FactoryFn(Injector injector); | |
4 | |
5 /** | |
6 * Creation strategy is asked to return an instance of the type after | |
7 * [Injector.get] locates the defining injector that has no instance cached. | |
8 * [directInstantation] is true when an instance is created directly from | |
9 * [Injector.instantiate]. | |
10 */ | |
11 typedef dynamic CreationStrategy( | |
12 Injector requesting, | |
13 Injector defining, | |
14 dynamic factory() | |
15 ); | |
16 | |
17 /** | |
18 * Visibility determines if the instance in the defining module is visible to | |
19 * the requesting injector. If true is returned, then the instance from the | |
20 * defining injector is provided. If false is returned, the injector keeps | |
21 * walking up the tree to find another visible instance. | |
22 */ | |
23 typedef bool Visibility(Injector requesting, Injector defining); | |
24 | |
25 typedef Object TypeFactory(factory(Type)); | |
26 | |
27 /** | |
28 * A collection of type bindings. Once the module is passed into the injector, | |
29 * the injector creates a copy of the module and all subsequent changes to the | |
30 * module have no effect. | |
31 */ | |
32 class Module { | |
33 final Map<Type, _Provider> _providers = <Type, _Provider>{}; | |
34 final List<Module> _childModules = <Module>[]; | |
35 Map<Type, TypeFactory> _typeFactories = {}; | |
36 | |
37 Map<Type, TypeFactory> get typeFactories { | |
38 if (_childModules.isEmpty) { | |
39 return _typeFactories; | |
40 } | |
41 var tmp = new Map.from(_typeFactories); | |
42 _childModules.forEach((child) { | |
43 if (child.typeFactories != null) { | |
44 child.typeFactories.forEach((type, factory) { | |
45 tmp[type] = factory; | |
46 }); | |
47 } | |
48 }); | |
49 return tmp; | |
50 } | |
51 | |
52 set typeFactories(Map<Type, TypeFactory> factories) { | |
53 _typeFactories = factories; | |
54 } | |
55 | |
56 Map<Type, _Provider> _providersCache; | |
57 | |
58 /** | |
59 * Compiles and returs bindings map by performing depth-first traversal of the | |
60 * child (installed) modules. | |
61 */ | |
62 Map<Type, _Provider> get _bindings { | |
63 if (_isDirty) { | |
64 _providersCache = <Type, _Provider>{}; | |
65 _childModules.forEach((child) => _providersCache.addAll(child._bindings)); | |
66 _providersCache.addAll(_providers); | |
67 } | |
68 return _providersCache; | |
69 } | |
70 | |
71 /** | |
72 * Register binding to a concrete value. | |
73 * | |
74 * The [value] is what actually will be injected. | |
75 */ | |
76 void value(Type id, value, | |
77 {CreationStrategy creation, Visibility visibility}) { | |
78 _dirty(); | |
79 _providers[id] = new _ValueProvider(value, creation, visibility); | |
80 } | |
81 | |
82 /** | |
83 * Register binding to a [Type]. | |
84 * | |
85 * The [implementedBy] will be instantiated using [new] operator and the | |
86 * resulting instance will be injected. If no type is provided, then it's | |
87 * implied that [id] should be instantiated. | |
88 */ | |
89 void type(Type id, {Type implementedBy, CreationStrategy creation, | |
90 Visibility visibility}) { | |
91 _dirty(); | |
92 _providers[id] = new _TypeProvider( | |
93 implementedBy == null ? id : implementedBy, creation, visibility); | |
94 } | |
95 | |
96 /** | |
97 * Register binding to a factory function.abstract | |
98 * | |
99 * The [factoryFn] will be called and all its arguments will get injected. | |
100 * The result of that function is the value that will be injected. | |
101 */ | |
102 void factory(Type id, FactoryFn factoryFn, | |
103 {CreationStrategy creation, Visibility visibility}) { | |
104 _dirty(); | |
105 _providers[id] = new _FactoryProvider(factoryFn, creation, visibility); | |
106 } | |
107 | |
108 /** | |
109 * Installs another module into this module. Bindings defined on this module | |
110 * take precidence over the installed module. | |
111 */ | |
112 void install(Module module) { | |
113 _childModules.add(module); | |
114 _dirty(); | |
115 } | |
116 | |
117 _dirty() { | |
118 _providersCache = null; | |
119 } | |
120 | |
121 bool get _isDirty => | |
122 _providersCache == null || _childModules.any((m) => m._isDirty); | |
123 } | |
124 | |
125 /** Deafault creation strategy is to instantiate on the defining injector. */ | |
126 dynamic _defaultCreationStrategy(Injector requesting, Injector defining, | |
127 dynamic factory()) => factory(); | |
128 | |
129 /** By default all values are visible to child injectors. */ | |
130 bool _defaultVisibility(_, __) => true; | |
131 | |
132 | |
133 typedef Object ObjectFactory(Type type, Injector requestor); | |
134 | |
135 abstract class _Provider { | |
136 final CreationStrategy creationStrategy; | |
137 final Visibility visibility; | |
138 | |
139 _Provider(this.creationStrategy, this.visibility); | |
140 | |
141 dynamic get(Injector injector, Injector requestor, ObjectFactory getInstanceBy
Type, error); | |
142 } | |
143 | |
144 class _ValueProvider extends _Provider { | |
145 dynamic value; | |
146 | |
147 _ValueProvider(this.value, [CreationStrategy creationStrategy, | |
148 Visibility visibility]) | |
149 : super(creationStrategy, visibility); | |
150 | |
151 dynamic get(Injector injector, Injector requestor, ObjectFactory getInstanceBy
Type, error) => | |
152 value; | |
153 } | |
154 | |
155 class _TypeProvider extends _Provider { | |
156 final Type type; | |
157 | |
158 _TypeProvider(this.type, [CreationStrategy creationStrategy, | |
159 Visibility visibility]) | |
160 : super(creationStrategy, visibility); | |
161 | |
162 dynamic get(Injector injector, Injector requestor, ObjectFactory getInstanceBy
Type, error) => | |
163 injector.newInstanceOf(type, getInstanceByType, requestor, error); | |
164 | |
165 } | |
166 | |
167 class _FactoryProvider extends _Provider { | |
168 final Function factoryFn; | |
169 | |
170 _FactoryProvider(this.factoryFn, [CreationStrategy creationStrategy, | |
171 Visibility visibility]) | |
172 : super(creationStrategy, visibility); | |
173 | |
174 dynamic get(Injector injector, Injector requestor, getInstanceByType, error) =
> | |
175 factoryFn(injector); | |
176 } | |
OLD | NEW |