15

简单场景:

我有多个实现通用接口的服务。所有这些服务都在该bootstrap方法中注册。

现在我想要另一个服务,它注入所有实现公共接口的注册服务。

IE

export interface MyInterface {
    foo(): void;
}

export class Service1 implements MyInterface {
    foo() { console.out("bar"); }
}

export class Service2 implements MyInterface {
    foo() { console.out("baz"); }
}

export class CollectorService {
    constructor(services:MyInterface[]) {
        services.forEach(s => s.foo());
    }
}

这有可能吗?

4

2 回答 2

16

您需要像这样注册您的服务提供商:

boostrap(AppComponent, [
  provide(MyInterface, { useClass: Service1, multi:true });
  provide(MyInterface, { useClass: Service2, multi:true });
]);

这仅适用于不具有接口的类,因为接口在运行时不存在。

要使其与接口一起使用,您需要对其进行调整:

bootstrap(AppComponent, [
  provide('MyInterface', { useClass: Service1, multi:true }),
  provide('MyInterface', { useClass: Service2, multi:true }),
  CollectorService
]);

并以这种方式注入:

@Injectable()
export class CollectorService {
  constructor(@Inject('MyInterface') services:MyInterface[]) {
    services.forEach(s => s.foo());
  }
}

有关更多详细信息,请参阅此 plunkr:https ://plnkr.co/edit/HSqOEN?p=preview 。

有关详细信息,请参阅此链接:

于 2016-03-10T12:34:21.450 回答
8

因为接口在运行时不可用(仅用于静态检查)接口不能用作 DI 的令牌。

改用令牌:

(已弃用)https://angular.io/api/core/OpaqueToken

var myInterfaceToken = new OpaqueToken('MyInterface');

https://angular.io/api/core/InjectionToken

var myInterfaceToken new InjectionToken<MyInterface>('MyInterface');
// import `myInterfaceToken` to make it available in this file

@NgModule({
  providers: [ 
    { provide: myInterfaceToken, useClass: Service1, multi:true },
    { provide: myInterfaceToken, useClass: Service2, multi:true },
  ],
  boostrap: [AppComponent],
)
class AppComponent {}
// import `myInterfaceToken` to make it available in this file

export class CollectorService {
    constructor(@Inject(myInterfaceToken) services:MyInterface[]) {
        services.forEach(s => s.foo());
    }
}
于 2016-03-10T12:40:33.350 回答