@kayahr/di
    Preparing search index...

    Factory dependencies

    Factory functions and static factory methods can be registered with injector.setFactory():

    class Foo {}

    function createFoo(): Foo {
    return new Foo();
    }

    injector.setFactory(Foo, createFoo);

    Static factory methods work the same way:

    class Bar {
    private constructor() {}

    public static create(): Bar {
    return new Bar();
    }
    }

    injector.setFactory(Bar, Bar.create);

    Static factory methods can also be registered with the injectable decorator. Classes instantiated with a factory method can even have a private constructor:

    class Service {
    private constructor() {}

    @injectable
    public static create(): Service {
    return new Service();
    }
    }

    The injectable decorator on static factory methods accepts the same options object as injector.setFactory().

    If a factory function or method has parameters then the parameter types must be specified with the inject option:

    class Component {
    private constructor(service: Service) {}

    @injectable({ inject: [ Service ] })
    public static create(service: Service): Component {
    return new Component(service);
    }
    }

    Factories can also be qualified with one or more injection tokens:

    import { InjectionToken, injectable } from "@kayahr/di";

    const componentToken = new InjectionToken<Component>("some-component");

    class Component {
    @injectable({ token: componentToken })
    public static create(): Component {
    return new Component();
    }
    }

    Just like with classes, tokens are also useful for interfaces because interfaces do not exist at runtime.

    Factories support the same lifetimes as classes:

    import { Lifetime, injectable } from "@kayahr/di";

    class Component {
    @injectable({ lifetime: Lifetime.TRANSIENT })
    public static create(): Component {
    return new Component();
    }
    }

    Factory functions and methods can also return promises:

    class UserDAO {
    private constructor(private readonly db: Database) {}

    @injectable({ inject: [ DBService ] })
    public static async create(dbService: DBService): Promise<UserDAO> {
    return new UserDAO(await dbService.connect());
    }
    }

    If a dependency depends on an asynchronous dependency then it automatically also becomes asynchronous:

    @injectable({ inject: [ UserDAO ] })
    class Component {
    public constructor(userDAO: UserDAO) {}
    }

    injector.get(Component) now returns a promise on the first call because instance creation must wait for UserDAO.

    Transient factory dependencies also support pass-through parameters:

    import { Lifetime, injectable, injector } from "@kayahr/di";

    class Component {
    @injectable({ inject: [ null, Service, null ], lifetime: Lifetime.TRANSIENT })
    public static create(name: string, service: Service, id: number): Component {
    return new Component();
    }
    }

    Resolve such a dependency like this:

    const component = injector.getSync(Component, { args: [ "test", 32 ] });
    

    Because the pass-through positions are only known from the runtime registration, args can not be typed precisely. TypeScript therefore does not validate the number or types of the passed values here.