- It's easy to forget to make a mapping, and developers want non-silent fails in these cases.
- Usage of extensions such as the SignalCommandMap becomes brittle, e.g. if the SCM silently-fails when a parameter isn't passed to the signal correctly.
- If you just want a new instance to fulfil each slot in your dependency tree, it would be nice to be able to use the injector to construct that object tree without having to make numerous mappings.
A fallbackProvider is where the injector turns for help when it doesn't have a mapping.
- Set through the
injector.fallbackProvider
property (default isnull
). - Either a class or instance.
- Must implement
FallbackDependencyProvider
. - If a class is provided, a new instance of this class will be created for each dependency, with the dependency type passed to the constructor.
- If an instance is provided, the same instance will be used for all dependencies.
- Must implement the
satisfies
method, which returns a boolean saying whether it can or can't provide for this type.
- Local mappings
- Parent (and ancestor) mappings
- Local fallbackProvider
- Parent (and ancestor) fallbackProviders (unless the
blockParentFallbackProvider
flag is set) - Explode with
InjectorMissingMappingError
The satisfies
method now returns a boolean which essentially says whether or not you can getInstance
for this type (and name).
The satisfiesDirectly
method says whether you can getInstance
without referring to ancestors.
If there is a fallbackProvider it will be checked.
- Unnamed injection only.
- Not available for common base types (Array, Boolean, Class, Function, int, Number, Object, String, uint) as these aren't sensible without names.
- Can support injection of interfaces if the fallbackProvider supports this.
- Can support async providers if you return a promise.
- Can be a facade delegating to a number of custom fallbackProviders.
- Setting
blockParentFallbackProvider
flag on the injector prevents the injector from consulting ancestors. This only applies to fallback providers; parent mappings can still be used. Useful for child injectors in extensions.
- Can provide an injector-instantiated instance of any Class.
- Does not support interfaces.
To configure your injector to always allow instantiation of unmapped types requested for injection, just do:
injector.fallbackProvider = ClassProvider;
The ClassProvider
uses injector.instantiateUnmapped
internally, so injected types can have nested injections fulfilled too.
- Regardless of any mappings.
- Ignores any fallbackProvider.
- Can only be used for classes, not interfaces (type must have a constructor).
- Will use mappings / fallbackProvider for the dependency tree.
- In the case where you have relevant mappings but you don't want to use mappings / fallbackProvider for the dependency tree, you have options such as:
- Make a normal factory.
- Roll a (non fallback) DependencyProvider that implements this and map the top type to this provider.
- Roll a fallbackProvider that forwards to a provider like the one in (2).
- Consider a different architecture, e.g. Entity based, for this part of the system.
Provides a single point of entry to obtain a mapped instance if one exists, or a new instance if one doesn't, with identical constraints and flexibility to the methods it wraps.
Essentially a sugar method so:
var instance:SomeType = injector.getOrCreateNewInstance(SomeType);
is equivalent to
var instance:SomeType = injector.satisfies(SomeType)
? injector.getInstance(SomeType)
: injector.instantiateUnmapped(SomeType);
This method doesn't support names. If you know you need a name then you should always use getInstance(type, name)
;