使用reflect-metadata获取ts类型

166 阅读1分钟
import 'reflect-metadata';

// 容器实现
class Container {
    private services: Map<string, any> = new Map();

    register(name: string, instance: any) {
        this.services.set(name, instance); // 将服务名称转为小写
    }

    get<T>(name: string): T {
        const service = this.services.get(name); // 从容器获取时也转为小写
        if (!service) {
            throw new Error(`Service not found: ${name}`);
        }
        return service;
    }
}

// 创建一个全局容器实例
const container = new Container();

// 装饰器实现:用于注册服务
function Injectable(constructor: Function) {
    const instance = new (constructor as any)(); // 创建类实例
    if(container.get(constructor.name)){
        console.error("已经注册该服务")
        return 
    }
    container.register(constructor.name, instance); // 使用类名注册服务
}

// 装饰器实现:用于属性注入
function Inject(target: any, propertyKey: string) {
    const type = Reflect.getMetadata("design:type", target, propertyKey); // 获取属性类型
    const serviceName = type.name; // 获取类型名称
    const value = container.get(serviceName); // 从容器获取实例
    target[propertyKey] = value; // 将实例赋值给目标属性
}

// 示例服务
@Injectable
class MyService {
    sayHello() {
        return 'Hello, world!';
    }
}

// 示例组件,使用属性注入
@Injectable
class MyComponent {
    @Inject // 自动注入 MyService 实例
    private myService!:MyService; // 使用非空断言

    greet() {
        return this.myService.sayHello();
    }
}

// 创建 MyComponent 实例
const myComponent = new MyComponent();
console.log(myComponent.greet()); // 输出: Hello, world!