【发布时间】:2020-05-14 06:49:24
【问题描述】:
我有一个 DI 容器类,它需要解析的类用 @Injectable() 装饰器装饰,以便被装饰的类发出元数据并进行进一步配置(很像 Angular DI 的工作原理,@987654321 @)。
为了将第三方类注册到我的容器中,我需要将 @Injectable 装饰器应用于我无法修改的类。想想我想在我的容器中安装的 node_modules 中安装的记录器库之类的东西。
有没有办法将装饰器应用于第三方类?我正在考虑类似的事情:
import {Container, Injectable} from "./Container";
import {Logger} from "@vendor/logger";
const container = new Container();
container.register(Logger, { useClass: Logger }); // not possible, since Logger is not decorated
container.register(decorate(Logger, Injectable), { useClass: Logger }); // something like this, which would allow for decorating a class with a certain decorator
我现在能想到的唯一解决方案是创建一个从真实记录器类扩展而来的装饰代理类。但是代理所有第三方类似乎开销很大。
还有其他想法吗?
编辑以提供更多信息:
@Injectable 装饰器是必需的,因为非装饰类不会发出元数据(这会使容器无法读取和解析其依赖项)。它只是通过将元数据键添加到具有__INJECTABLE 键和true 值的修饰类中来实现 - 每当在容器中注册新服务时,它都会检查是否设置了__INJECTABLE 标志,否则抛出错误.
这是一个代理类的例子:
import {Container, Injectable} from "./Container";
import {Logger as ParentLogger} from "@vendor/logger";
// Proxy
@Injectable()
class Logger extends ParentLogger {
}
const container = new Container();
container.register(Logger, { useClass: Logger });
我猜这个应该工作,但需要为几乎所有第三方类创建代理。
【问题讨论】:
-
可能可以通过
decorate函数创建代理,但从您的描述中不清楚如何使用Injectable。也许如果你能提供一个手动创建代理的例子,你可能会得到一些关于如何自动完成的反馈。 -
添加了更多解释。
标签: typescript