DynamicInjector class
Dynamic implementation of Injector that uses mirrors.
class DynamicInjector extends Injector { DynamicInjector({List<Module> modules, String name, bool allowImplicitInjection: false}) : super(modules: modules, name: name, allowImplicitInjection: allowImplicitInjection); DynamicInjector._fromParent(List<Module> modules, Injector parent, {name}) : super.fromParent(modules, parent, name: name); newFromParent(List<Module> modules, String name) { return new DynamicInjector._fromParent(modules, this, name: name); } Object newInstanceOf(Type type, ObjectFactory getInstanceByType, Injector requestor, error) { var classMirror = reflectType(type); if (classMirror is TypedefMirror) { throw new NoProviderError(error('No implementation provided ' 'for ${getSymbolName(classMirror.qualifiedName)} typedef!')); } MethodMirror ctor = classMirror.declarations[classMirror.simpleName]; resolveArgument(int pos) { ParameterMirror p = ctor.parameters[pos]; if (p.type is TypedefMirror) { throw new NoProviderError( error('Cannot create new instance of a typedef ${p.type}')); } return getInstanceByType(getReflectedTypeWorkaround(p.type), requestor); } var args = new List.generate(ctor.parameters.length, resolveArgument, growable: false); return classMirror.newInstance(ctor.constructorName, args).reflectee; } /** * Invoke given function and inject all its arguments. * * Returns whatever the function returns. */ dynamic invoke(Function fn) { ClosureMirror cm = reflect(fn); MethodMirror mm = cm.function; int position = 0; List args = mm.parameters.map((ParameterMirror parameter) { try { return get(getReflectedTypeWorkaround(parameter.type)); } on NoProviderError catch (e) { throw new NoProviderError(e.message); } finally { position++; } }).toList(); return cm.apply(args).reflectee; } }
Extends
Injector > DynamicInjector
Constructors
new DynamicInjector({List<Module> modules, String name, bool allowImplicitInjection: false}) #
Creates a new Object
instance.
Object
instances have no meaningful state, and are only useful
through their identity. An Object
instance is equal to itself
only.
DynamicInjector({List<Module> modules, String name, bool allowImplicitInjection: false}) : super(modules: modules, name: name, allowImplicitInjection: allowImplicitInjection);
Properties
final Map<Type, Object> instances #
final Map<Type, Object> instances = <Type, Object>{}
final String name #
Name of the injector or null of none is given.
final String name
Methods
Injector createChild(List<Module> modules, {List<Type> forceNewInstances, String name}) #
Create a child injector.
Child injector can override any bindings by adding additional modules.
It also accepts a list of tokens that a new instance should be forced. That means, even if some parent injector already has an instance for this token, there will be a new instance created in the child injector.
Injector createChild(List<Module> modules, {List<Type> forceNewInstances, String name}) { if (forceNewInstances != null) { Module forceNew = new Module(); forceNewInstances.forEach((type) { var providerWithInjector = _getProviderWithInjectorForType(type); var provider = providerWithInjector.provider; forceNew.factory(type, (Injector inj) => provider.get(this, inj, inj._getInstanceByType, inj._error), creation: provider.creationStrategy, visibility: provider.visibility); }); modules = modules.toList(); // clone modules.add(forceNew); } return newFromParent(modules, name); }
dynamic get(Type type) #
Get an instance for given token (Type
).
If the injector already has an instance for this token, it returns this instance. Otherwise, injector resolves all its dependencies, instantiate new instance and returns this instance.
If there is no binding for given token, injector asks parent injector.
If there is no parent injector, an implicit binding is used. That is,
the token (Type
) is instantiated.
dynamic get(Type type) => _getInstanceByType(type, this);
dynamic invoke(Function fn) #
Invoke given function and inject all its arguments.
Returns whatever the function returns.
dynamic invoke(Function fn) { ClosureMirror cm = reflect(fn); MethodMirror mm = cm.function; int position = 0; List args = mm.parameters.map((ParameterMirror parameter) { try { return get(getReflectedTypeWorkaround(parameter.type)); } on NoProviderError catch (e) { throw new NoProviderError(e.message); } finally { position++; } }).toList(); return cm.apply(args).reflectee; }
dynamic newFromParent(List<Module> modules, String name) #
newFromParent(List<Module> modules, String name) { return new DynamicInjector._fromParent(modules, this, name: name); }
Object newInstanceOf(Type type, ObjectFactory getInstanceByType, Injector requestor, error) #
Object newInstanceOf(Type type, ObjectFactory getInstanceByType, Injector requestor, error) { var classMirror = reflectType(type); if (classMirror is TypedefMirror) { throw new NoProviderError(error('No implementation provided ' 'for ${getSymbolName(classMirror.qualifiedName)} typedef!')); } MethodMirror ctor = classMirror.declarations[classMirror.simpleName]; resolveArgument(int pos) { ParameterMirror p = ctor.parameters[pos]; if (p.type is TypedefMirror) { throw new NoProviderError( error('Cannot create new instance of a typedef ${p.type}')); } return getInstanceByType(getReflectedTypeWorkaround(p.type), requestor); } var args = new List.generate(ctor.parameters.length, resolveArgument, growable: false); return classMirror.newInstance(ctor.constructorName, args).reflectee; }