Почему моя попытка внедрения свойства не вводит ничего, кроме неопределенного?

У меня есть существующий проект машинописного текста, использующий Inversify. Я определил регистратор в моих типах в TYPES.ILoggger и когда я получаю доступ к логгеру прямо из моего контейнера, он работает:

import {ILogger} from "./interfaces/ILogger";
import {TYPES} from "./interfaces/TYPES";
import container from "./kernel/inversify.config";

const loggerFromTheContainer: ILogger = container.get<ILogger>(TYPES.ILogger);
loggerFromTheContainer.info("I WILL LOG"); // this works

Так что мои настройки должны быть в порядке.

Я не хочу получать доступ к контейнеру напрямую, но хочу использовать инъекцию свойства. [REVME InversifyJS'предоставляет пример:

Если вы предпочитаете это, вы можете использовать внедрение свойства вместо внедрения конструктора, поэтому вам не нужно объявлять конструктор класса:

@injectable()
class Ninja implements Warrior {
    @inject(TYPES.Weapon) private _katana: Weapon;
    @inject(TYPES.ThrowableWeapon) private _shuriken: ThrowableWeapon;
    public fight() { return this._katana.hit(); }
    public sneak() { return this._shuriken.throw(); }
}

и я пытаюсь следовать этому.

Тем не менее, когда я пытаюсь внедрить регистратор через внедрение свойства, я внезапно получаю undefined как регистратор, и я не знаю почему:

@injectable()
class ShouldHaveLogger {
    @inject(TYPES.ILogger) private logger: ILogger;

    constructor() {
        this.logger.info("Hello World"); // this.logger will remain undefined
    }
}

new ShouldHaveLogger();

Это бросит общий

TypeError: Cannot read property 'info' of undefined

как this.logger не вводится. Но почему и как это исправить?

1 ответ

Обычное поведение внедрения свойства - позволить inversify создавать экземпляры для вас. Теперь вы описываете сценарий использования, в котором вы создаете экземпляр ShouldHaveLogger себя (или другая библиотека создаёт это для вас).

Это также указано в документах

Для этого вам понадобятся https://github.com/inversify/inversify-inject-decorators, так как тогда вы можете внедрить регистратор, например, через @lazyInject, У вас есть верхняя настройка lazyInject, использующая ваш контейнер, и ваш код должен выглядеть так:

import {injectable} from "inversify";
import getDecorators from "inversify-inject-decorators";
import {ILogger} from "./interfaces/ILogger";
import {TYPES} from "./interfaces/TYPES";
import container from "./kernel/inversify.config";   

const {lazyInject} = getDecorators(container);

@injectable()
class ShouldHaveLogger {
    @lazyInject(TYPES.ILogger) private logger: ILogger;

    constructor() {
        this.logger.info("I am working now");
    }
}

new ShouldHaveLogger();

Будет печатать в зависимости от вашей реализации логгера:

2019-01-30T09:47:54.890Z - info: "I am working now"
Другие вопросы по тегам