Typescript/NodeJS - 与工厂合作时的循环依赖

Typescript/NodeJS - Circular Dependency while working with factories

我对 Typescript 和 NodeJS 很陌生,我正在尝试使用工厂在运行时创建对象。

例如,以下对象具有 属性 类型的文本,现在在运行时获取它,我想创建一个 TextContainer 实例:

{
type: "Text", 
name: "Title"
}

我的工厂是这样的:

import {BaseContainer} from "../Containers/BaseContainer";
import {TextContainer} from "../Containers/TextContainer";
/**
 * Used to dynamically create objects with different container classes
 * in runtime
 */
export class ContainerFactory {

    // Object containing all class names and types
    private dictionary: Object;

    /**
     * Initializes factory dictionary
     */
    constructor() {
        // Initialize dictionary with classes
        this.dictionary = {
            "default": BaseContainer,
            "Text": TextContainer,
            "TextContainer": TextContainer
        }
    }

    /**
     * Builds object depending on className
     * @param className
     * @param params
     */
    build(className: string, params: Object) {
        // Return new class of type className, if not found
        // return object with class of set default class
        return className in this.dictionary ? new this.dictionary[className](params) : new this.dictionary['default'];

    }
}

问题出现在 BaseContainer class 中(它由 TextContainer 扩展,并将由更多 classes 扩展,将出现在这个工厂中)我在一个函数,这里是循环依赖,因为在 BaseContainer 中我导入了 ContainerFactory,而在 ContainerFactory 中导入了 BaseContainer。

我需要 BaseContainer 中的工厂,因为我有一个树状层次结构并且容器有子容器,它们本身就是容器。

对于如何解决此问题或如何折射我的代码以使其可靠工作的建议,我将不胜感激。 我搜索了类似的问题,但还没有找到解决方法。

我在 TextContainer class(扩展 BaseContainer)中收到以下错误:

extendStatics(d, b);
        ^

TypeError: Object prototype may only be an Object or null: undefined

此任务的更好解决方案是使用装饰器将类型名称映射到相应的构造函数。例如:

Decorator.ts:

export function Container(className: string)
{
    return (target: any) =>
    {
        Meta.classNameToCtor[!!className ? className : target.name] = target;
    };
}

Meta.ts:

export class Meta
{
    public static classNameToCtor: {[key: string]: any} = {};
}

现在您需要做的就是像这样装饰每个容器 类:

@Container("default")
export class BaseContainer {...}

并在您的工厂中通过 Meta:

访问构造函数
build(className: string, params: Object) 
{
    return className in Meta.classNameToCtor ? new Meta.classNameToCtor[className](params) : new Meta.classNameToCtor['default'];
}

这种方法完全消除了导入依赖关系,scalable/elegant 更易用。