Почему моя попытка внедрения свойства не вводит ничего, кроме неопределенного?
У меня есть существующий проект машинописного текста, использующий 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"