@inject

:point_right: Make sure to first read the introduction to dependency injection.

@inject together with @injectable allow for simple dependency injection (“DI”).

@inject (no parameter)

Decorate a constructor parameter to inject a value based on the type of the parameter, e.g.:

import {inject, create} from 'tabris-decorators';
import {ClassB} from './ClassB';

export class ClassA {

  constructor(@inject b: ClassB) {
    ...
  }

}

ClassB has to to have a registered injection handler, which can be achieved using @injectable, @shared, @injectionHandler, or by using the Injector class method “addHandler”. To create instances of ClassA you must use the create method which handles the injections:

import {create} from 'tabris-decorators';
import {classA} from './ClassA';

const a = create(ClassA);

If ClassA itself is injected somewhere the injections are taken care of by @inject.

The type of the injection - i.e. the type of the parameter decorated with @inject - has to be a class. Interfaces and advanced types are not supported. However, abstract classes and classes merged with interfaces work. Since classes can be used like interfaces most traditional dependency injection patterns can still be used.

JSX

Widgets (custom components) may also use @inject. If they are used as a JSX element all injections are automatically resolved using the global injector. However, the first constructor parameter can then not be used for injection since this is where the properties object is passed to by the JSX processor.

@inject(param)

Where param can be any object, string, number or boolean.

Like @inject, but allows to pass on a value to the injection handler. For further information see @injectable and @injectionHandler.

class Foo {

  constructor(@inject('some value') a: ClassA) {
    ...
  }

}