Injector
Make sure to first read the introduction to dependency injection and the
@inject
documentation.
All injection handler created by @injectable
, @shared
and @injectionHandler
are registered in a global Injector
instance exported as injector
. The injector can also be used without decorators as this non-TypeScript example shows.
create(type, …parameters)
Where type
can be any class and parameters
(optional) are of the same type as the constructor parameters.
Creates an instance of the given type and fulfils all the constructor injections. The type itself does not have to be injectable. If it was the resolve
method should be used instead. If parameters are given after the type they will be passed to the constructor, while all other constructor parameters will be injected (if decorated with @inject
).
Example:
class Foo {
constructor(a: ClassA, @inject b: ClassB, @inject c: ClassC) {
//...
}
}
let foo = create(Foo, new ClassA());
The create
method of the default global injector instance is also exported directly by 'tabris-decorators'
:
import {injector, create} from 'tabris-decorators';
console.log(injector.create === create);
resolve(type, injectionParameter?)
Where type
can be any class and injectionParameter
of any type.
Returns an instance for the given type, just like using the @inject
decorator would do in a constructor. Especially useful in cases where the @inject
decorator can not be used, e.g. outside of classes. Note that type
has to be injectable, i.e. have a compatible injection handler registered. The second parameter may be omitted, or be used to pass a value to the injection handler. For further information see @injectable(config)
and @injectionHandler(type)
.
The resolve
method of the default global injector instance is also exported directly by 'tabris-decorators'
:
import {injector, resolve} from 'tabris-decorators';
console.log(injector.resolve === resolve);
addHandler({targetType, handler, priority?})
Where targetType
is any class, handler
is a Function returning a targetType
instance and priority - if given - is a number
.
Explicitly registers a new injection handler for targetType
Same as using the injectionHandler
decorator attached to the same Injector
instance.
addHandler(targetType, handler)
Shorthand for addHandler({targetType, handler})
.
register(targetType, value)
Makes the given value available for injection as the given target type. This differs from @shared
in that it registers an existing instance, not a class that will be instantiated by the framework.
Same as calling addHandler(targetType, () => value)
.
The register
method of the default global injector instance is also exported directly by 'tabris-decorators'
.
Custom Injector instances
For unit tests or libraries it may be useful to create a separate Injector
instance to keep the registered injection handlers separate.
To use the custom injector in other module, import the decorators/functions not from tabris-decorators
but from a new module like this one:
import { Injector } from 'tabris-decorators';
export const injector = new Injector();
export const { inject, shared, injectable, injectionHandler, create, resolve} = injector;
export const JSX = injector.jsxProcessor;
Then import like this:
import { injector, inject, injectable, shared, injectionHandler, JSX } from './customInjector';
The JSX
object must be imported whenever JSX expressions are used that should resolve injections with the given injector.
The Injector instance that was used to create a given object may be obtained by Injector.get(object)
. That is necessary if an object needs an injector instance (e.g. for calling injector.create()
), but may be created by different injectors in different scenarios, for example in unit testing.
Example:
const newObject = Injector.get(this).create(InjectableType);