MST

星途 面试题库

面试题:TypeScript参数装饰器在依赖注入中的深度应用

在一个基于TypeScript的大型项目中,需要实现依赖注入功能。请设计并实现一套基于参数装饰器的依赖注入机制,确保依赖的正确解析和注入。解释在这种场景下,参数装饰器如何与其他设计模式(如工厂模式、单例模式)协同工作,以提高代码的可维护性和可扩展性。
22.3万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

1. 基于参数装饰器的依赖注入机制设计与实现

定义依赖容器

class Container {
    private dependencies: Map<string, any> = new Map();

    register(key: string, value: any) {
        this.dependencies.set(key, value);
    }

    resolve(key: string) {
        return this.dependencies.get(key);
    }
}

const container = new Container();

定义参数装饰器

function inject(key: string) {
    return function (target: any, propertyKey: string | symbol, parameterIndex: number) {
        const originalMethod = target[propertyKey];
        target[propertyKey] = function (...args: any[]) {
            const dependency = container.resolve(key);
            args.splice(parameterIndex, 0, dependency);
            return originalMethod.apply(this, args);
        };
    };
}

使用示例

class Service {
    message = 'Hello from Service';
}

class Component {
    @inject('Service')
    doSomething(service: Service) {
        console.log(service.message);
    }
}

container.register('Service', new Service());
const component = new Component();
component.doSomething(); 

2. 与其他设计模式协同工作

与工厂模式协同工作

  • 工厂模式作用:工厂模式用于创建对象,在依赖注入场景中,可用于创建复杂对象。例如,如果Service对象创建过程复杂,需要特定的初始化参数等,可使用工厂模式。
  • 协同方式:修改Containerregister方法,使其支持工厂函数注册。
class Container {
    private dependencies: Map<string, any> = new Map();

    register(key: string, factory: () => any) {
        this.dependencies.set(key, factory());
    }

    resolve(key: string) {
        return this.dependencies.get(key);
    }
}
  • 优势:提高了对象创建的灵活性,使得依赖对象的创建逻辑可以集中管理,增强代码的可维护性和可扩展性。例如,当Service对象的创建逻辑发生变化时,只需修改工厂函数,而不会影响到依赖注入的其他部分。

与单例模式协同工作

  • 单例模式作用:单例模式确保一个类只有一个实例,并提供全局访问点。在依赖注入中,对于一些需要全局唯一的依赖对象,如数据库连接对象,使用单例模式可避免重复创建,节省资源。
  • 协同方式:在Containerregister方法中实现单例逻辑。
class Container {
    private dependencies: Map<string, any> = new Map();

    register(key: string, value: any) {
        if (!this.dependencies.has(key)) {
            this.dependencies.set(key, value);
        }
    }

    resolve(key: string) {
        return this.dependencies.get(key);
    }
}
  • 优势:保证依赖对象的唯一性,在整个项目中,无论何处需要注入该依赖,都将得到同一个实例。这对于维护全局状态或共享资源的对象非常重要,同时也提高了代码的可维护性,因为开发人员无需担心多个实例可能带来的不一致问题。