OLD | NEW |
| (Empty) |
1 library di.dynamic_injector; | |
2 | |
3 import 'di.dart'; | |
4 import 'mirrors.dart'; | |
5 | |
6 /** | |
7 * Dynamic implementation of [Injector] that uses mirrors. | |
8 */ | |
9 class DynamicInjector extends Injector { | |
10 | |
11 DynamicInjector({List<Module> modules, String name, | |
12 bool allowImplicitInjection: false}) | |
13 : super(modules: modules, name: name, | |
14 allowImplicitInjection: allowImplicitInjection); | |
15 | |
16 DynamicInjector._fromParent(List<Module> modules, Injector parent, {name}) | |
17 : super.fromParent(modules, parent, name: name); | |
18 | |
19 newFromParent(List<Module> modules, String name) { | |
20 return new DynamicInjector._fromParent(modules, this, name: name); | |
21 } | |
22 | |
23 Object newInstanceOf(Type type, ObjectFactory getInstanceByType, | |
24 Injector requestor, error) { | |
25 var classMirror = reflectType(type); | |
26 if (classMirror is TypedefMirror) { | |
27 throw new NoProviderError(error('No implementation provided ' | |
28 'for ${getSymbolName(classMirror.qualifiedName)} typedef!')); | |
29 } | |
30 | |
31 MethodMirror ctor = classMirror.declarations[classMirror.simpleName]; | |
32 | |
33 if (ctor == null) { | |
34 throw new NoProviderError('Unable to find default constructor for $type. ' | |
35 'Make sure class has a default constructor.' + | |
36 (1.0 is int ? | |
37 ' Make sure you have correctly configured @MirrorsUsed.' : '')); | |
38 } | |
39 | |
40 resolveArgument(int pos) { | |
41 ParameterMirror p = ctor.parameters[pos]; | |
42 if (MirrorSystem.getName(p.type.qualifiedName) == 'dynamic') { | |
43 var name = MirrorSystem.getName(p.simpleName); | |
44 throw new NoProviderError(error("The '$name' parameter must be typed")); | |
45 } | |
46 if (p.type is TypedefMirror) { | |
47 throw new NoProviderError( | |
48 error('Cannot create new instance of a typedef ${p.type}')); | |
49 } | |
50 return getInstanceByType(getReflectedTypeWorkaround(p.type), requestor); | |
51 } | |
52 | |
53 var args = new List.generate(ctor.parameters.length, resolveArgument, | |
54 growable: false); | |
55 return classMirror.newInstance(ctor.constructorName, args).reflectee; | |
56 } | |
57 | |
58 /** | |
59 * Invoke given function and inject all its arguments. | |
60 * | |
61 * Returns whatever the function returns. | |
62 */ | |
63 dynamic invoke(Function fn) { | |
64 ClosureMirror cm = reflect(fn); | |
65 MethodMirror mm = cm.function; | |
66 int position = 0; | |
67 List args = mm.parameters.map((ParameterMirror parameter) { | |
68 try { | |
69 return get(getReflectedTypeWorkaround(parameter.type)); | |
70 } on NoProviderError catch (e) { | |
71 throw new NoProviderError(e.message); | |
72 } finally { | |
73 position++; | |
74 } | |
75 }).toList(); | |
76 | |
77 return cm.apply(args).reflectee; | |
78 } | |
79 } | |
OLD | NEW |