【问题标题】:TSyringe inject all classes that implements some interfaceTSyringe 注入所有实现某个接口的类
【发布时间】:2021-09-27 22:45:07
【问题描述】:

我一直在寻找 TSyringe 是否可以注入所有实现某个接口(或从抽象类扩展)的类,如下所示:

@injectable()
export interface IService {
    foo(): void;
}

@injectable()
export class Service1 implements IService {
    foo() { console.out("bar"); }
}

@injectable()
export class Service2 implements IService {
    foo() { console.out("baz"); }
}

export class CollectorService {
    constructor(
        @inject('Service')
        services: IService[]
    ) {
        services.forEach(s => s.foo());
    }
}

我一个月前才开始使用 TSyringe,所以对所有功能都不熟悉,也不知道如何在 DI 容器中注册这种依赖项(如果有可能实现我的建议) . 我正在尝试模仿 Spring @Autowire 注释。

【问题讨论】:

    标签: typescript tsyringe


    【解决方案1】:

    我不知道这是否是最好的解决方案,但我可以用这个实现多次注入:

    import {
      injectable, injectAll, registry, container,
    } from 'tsyringe';
    
    interface ValueClass {
      value: string;
    
      sayMyValue(): void;
    }
    
    @injectable()
    @registry([{ token: 'ValueClass', useClass: ValueClass1 }])
    class ValueClass1 implements ValueClass {
      sayMyValue(): void {
        console.log('ValueClass1');
      }
    
      value: string = 'value1';
    }
    
    @injectable()
    @registry([{ token: 'ValueClass', useClass: ValueClass2 }])
    class ValueClass2 implements ValueClass {
      value: string;
    
      sayMyValue(): void {
        console.log('ValueClass2');
      }
    }
    
    @injectable()
    export class AppClass {
      constructor(
        @injectAll('ValueClass')
        private valueClasses: ValueClass[],
      ) { }
    
      run() {
        this.valueClasses
          .forEach((valueClass: ValueClass) => { valueClass.sayMyValue(); });
      }
    }
    
    const v = container.resolve(AppClass);
    v.run();
    

    【讨论】:

      【解决方案2】:

      我无法让每个类的 registry 像在 Aníbal Deboni Neto asnwer 中一样工作,但是使用代理类来放置对我有用的所有注册表。我还使用了Symbol,这样我就没有任何魔术字符串了。

      interface IBar {}
      
      @injectable()
      class Foo implements IBar {}
      @injectable()
      class Baz implements IBar {}
      
      @registry([
        {token: Bar.token, useToken: Foo},
        {token: Bar.token, useToken: Baz}
      ])
      abstract class Bar {
        static readonly token = Symbol("IBar");
      }
      
      @injectable()
      class User{
        constructor(@injectAll(Bar.token) private bars: IBar[]) {
        }
      }
      
      const bars: IBar[] = container.resolveAll<IBar>(Bar.token);
      const user: User = container.resolve(User);
      
      

      来源:https://github.com/microsoft/tsyringe#register

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-08
        • 1970-01-01
        • 2020-04-09
        • 1970-01-01
        • 1970-01-01
        • 2011-02-23
        相关资源
        最近更新 更多