Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: third_party/pkg/di/lib/src/base_injector.dart

Issue 257423008: Update all Angular libs (run update_all.sh). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 library di.base_injector;
2
3 import 'provider.dart';
4 import 'error_helper.dart';
5
6 import 'package:collection/collection.dart';
7 import 'package:di/di.dart';
8
9 List<Key> _PRIMITIVE_TYPES = new UnmodifiableListView(<Key>[
10 new Key(num), new Key(int), new Key(double), new Key(String),
11 new Key(bool)
12 ]);
13
14 bool _defaultVisibility(_, __) => true;
15
16 const ResolutionContext _ZERO_DEPTH_RESOLVING =
17 const ResolutionContext(0, null, null);
18
19 abstract class BaseInjector implements Injector, ObjectFactory {
20
21 @override
22 final String name;
23
24 @override
25 final BaseInjector parent;
26
27 Injector _root;
28
29 List<Provider> _providers;
30 int _providersLen = 0;
31
32 final Map<Key, Object> _instances = <Key, Object>{};
33
34 @override
35 final bool allowImplicitInjection;
36
37 Iterable<Type> _typesCache;
38
39 Iterable<Type> get _types {
40 if (_providers == null) return [];
41
42 if (_typesCache == null) {
43 _typesCache = _providers
44 .where((p) => p != null)
45 .map((p) => p.type);
46 }
47 return _typesCache;
48 }
49
50 BaseInjector({List<Module> modules, String name,
51 bool allowImplicitInjection: false})
52 : this.fromParent(modules, null,
53 name: name, allowImplicitInjection: allowImplicitInjection);
54
55 BaseInjector.fromParent(List<Module> modules,
56 BaseInjector this.parent, {this.name, this.allowImplicitInjection}) {
57 _root = parent == null ? this : parent._root;
58 var injectorId = new Key(Injector).id;
59 _providers = new List(lastKeyId + 1);
60 _providersLen = lastKeyId + 1;
61 if (modules != null) {
62 modules.forEach((module) {
63 module.bindings.forEach((k, v) {
64 _providers[k] = v;
65 });
66 });
67 }
68 _providers[injectorId] = new ValueProvider(Injector, this);
69 }
70
71 @override
72 Injector get root => _root;
73
74 @override
75 Set<Type> get types {
76 var types = new Set.from(_types);
77 var parent = this.parent;
78 while (parent != null) {
79 types.addAll(parent._types);
80 parent = parent.parent;
81 }
82 return types;
83 }
84
85 Object getInstanceByKey(Key key, Injector requester, ResolutionContext resolvi ng) {
86 assert(_checkKeyConditions(key, resolving));
87
88 // Do not bother checking the array until we are fairly deep.
89 if (resolving.depth > 30 && resolvedTypes(resolving).contains(key)) {
90 throw new CircularDependencyError(
91 error(resolving, 'Cannot resolve a circular dependency!', key));
92 }
93
94 var providerWithInjector = _getProviderWithInjectorForKey(key, resolving);
95 var provider = providerWithInjector.provider;
96 var injector = providerWithInjector.injector;
97 var visible = provider.visibility != null ?
98 provider.visibility(requester, injector) :
99 _defaultVisibility(requester, injector);
100
101 if (visible && _instances.containsKey(key)) return _instances[key];
102
103 if (providerWithInjector.injector != this || !visible) {
104 if (!visible) {
105 if (injector.parent == null) {
106 throw new NoProviderError(
107 error(resolving, 'No provider found for ${key}!', key));
108 }
109 injector = injector.parent
110 ._getProviderWithInjectorForKey(key, resolving).injector;
111 }
112 return injector.getInstanceByKey(key, requester, resolving);
113 }
114
115 resolving = new ResolutionContext(resolving.depth + 1, key, resolving);
116 var value = provider.get(this, requester, this, resolving);
117
118 // cache the value.
119 providerWithInjector.injector._instances[key] = value;
120 return value;
121 }
122
123 /// Returns a pair for provider and the injector where it's defined.
124 _ProviderWithDefiningInjector _getProviderWithInjectorForKey(
125 Key key, ResolutionContext resolving) {
126 if (key.id < _providersLen) {
127 var provider = _providers[key.id];
128 if (provider != null) {
129 return new _ProviderWithDefiningInjector(provider, this);
130 }
131 }
132
133 if (parent != null) {
134 return parent._getProviderWithInjectorForKey(key, resolving);
135 }
136
137 if (allowImplicitInjection) {
138 return new _ProviderWithDefiningInjector(
139 new TypeProvider(key.type), this);
140 }
141
142 throw new NoProviderError(
143 error(resolving, 'No provider found for ${key}!', key));
144 }
145
146 bool _checkKeyConditions(Key key, ResolutionContext resolving) {
147 if (_PRIMITIVE_TYPES.contains(key)) {
148 throw new NoProviderError(
149 error(resolving,
150 'Cannot inject a primitive type of ${key.type}!', key));
151 }
152 return true;
153 }
154
155 @override
156 dynamic get(Type type, [Type annotation]) =>
157 getInstanceByKey(new Key(type, annotation), this, _ZERO_DEPTH_RESOLVING);
158
159 @override
160 dynamic getByKey(Key key) =>
161 getInstanceByKey(key, this, _ZERO_DEPTH_RESOLVING);
162
163 @override
164 Injector createChild(List<Module> modules,
165 {List forceNewInstances, String name}) =>
166 createChildWithResolvingHistory(modules, _ZERO_DEPTH_RESOLVING,
167 forceNewInstances: forceNewInstances,
168 name: name);
169
170 Injector createChildWithResolvingHistory(
171 List<Module> modules,
172 resolving,
173 {List forceNewInstances, String name}) {
174 if (forceNewInstances != null) {
175 Module forceNew = new Module();
176 forceNewInstances.forEach((key) {
177 if (key is Type) {
178 key = new Key(key);
179 } else if (key is! Key) {
180 throw 'forceNewInstances must be List<Key|Type>';
181 }
182 assert(key is Key);
183 var providerWithInjector =
184 _getProviderWithInjectorForKey(key, resolving);
185 var provider = providerWithInjector.provider;
186 forceNew.factoryByKey(key, (Injector inj) => provider.get(this,
187 inj, inj as ObjectFactory, resolving),
188 visibility: provider.visibility);
189 });
190
191 modules = modules.toList(); // clone
192 modules.add(forceNew);
193 }
194
195 return newFromParent(modules, name);
196 }
197
198 newFromParent(List<Module> modules, String name);
199
200 Object newInstanceOf(Type type, ObjectFactory factory, Injector requestor,
201 resolving);
202 }
203
204 class _ProviderWithDefiningInjector {
205 final Provider provider;
206 final BaseInjector injector;
207 _ProviderWithDefiningInjector(this.provider, this.injector);
208 }
209
210 /**
211 * Information about the context in which the [key] is being resolved, including
212 * dependency tree [depth] at which the key is being resolved, as well as
213 * [parent] context (used to determine circular dependencies).
214 */
215 class ResolutionContext {
216 final int depth;
217 final Key key;
218 final ResolutionContext parent;
219
220 const ResolutionContext(this.depth, this.key, this.parent);
221 }
OLDNEW
« no previous file with comments | « third_party/pkg/di/lib/reflected_type.dart ('k') | third_party/pkg/di/lib/src/error_helper.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698