为什么我的 属性 注入尝试没有注入未定义的任何东西?
Why is my property injection attempt not injecting anything but undefined?
我有一个使用 inversify 的现有打字稿项目。我在 TYPES.ILoggger
的 TYPES 中定义了一个记录器,当我直接从我的容器访问记录器时它起作用了:
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
所以我的设置应该没问题。
我不想直接访问容器,但我想使用 属性 注入。 [InversifyJS' README 提供了一个例子:
If you prefer it you can use property injection instead of constructor
injection so you don't have to declare the class constructor:
@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
没有被注入。然而,为什么以及如何解决它?
属性 注入的正常行为是让 inversify
为您创建实例。您现在正在描述一个用例,其中您自己创建了 ShouldHaveLogger
的实例(或者另一个库正在为您创建它)。
也指出了这一点
为此,您需要 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"
我有一个使用 inversify 的现有打字稿项目。我在 TYPES.ILoggger
的 TYPES 中定义了一个记录器,当我直接从我的容器访问记录器时它起作用了:
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
所以我的设置应该没问题。
我不想直接访问容器,但我想使用 属性 注入。 [InversifyJS' README 提供了一个例子:
If you prefer it you can use property injection instead of constructor injection so you don't have to declare the class constructor:
@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
没有被注入。然而,为什么以及如何解决它?
属性 注入的正常行为是让 inversify
为您创建实例。您现在正在描述一个用例,其中您自己创建了 ShouldHaveLogger
的实例(或者另一个库正在为您创建它)。
为此,您需要 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"