Dependency injection 将类绑定到接口

Dependency injection 将类绑定到接口,dependency-injection,typescript,angular,Dependency Injection,Typescript,Angular,使用typescript,我可以轻松地将类绑定到它们自己: bootstrap(MyAppComponent, [MyClass]); 但是,我希望将我的类绑定到一个接口,如下所示: boostrap(MyAppComponent, [???]); 这样我就可以按如下方式注入它: class MyAppComponent { constructor(my_class : IMyClass){ } }; 这在Angular2中可能吗?如果是,我必须如何指定绑定?要缩短它,问题

使用typescript,我可以轻松地将类绑定到它们自己:

bootstrap(MyAppComponent, [MyClass]);
但是,我希望将我的类绑定到一个接口,如下所示:

boostrap(MyAppComponent, [???]);
这样我就可以按如下方式注入它:

class MyAppComponent {
    constructor(my_class : IMyClass){
    }
};

这在Angular2中可能吗?如果是,我必须如何指定绑定?

要缩短它,问题是在编译typescript时接口会消失。因此,您必须使用带有字符串的@Inject

或者还有另一个选项,如果您选中,您可以在评论中找到:

一些背景。在TypeScript中,接口是结构化的,不会在运行时保留。因此,您必须按如下方式使用ILoginService:

class MyAppComponent {
    constructor(my_class : IMyClass){
    }
};
您不必使用字符串-任何对象都可以在其中传递。我们实际上提供了一个名为OpaqueToken的对象,可用于此目的

可以这样使用:


我不知道是否可以使用接口,因为接口在运行时不可用(javascript不知道接口)。 但是它可以使用抽象类来完成

//abstract-parent-service.ts

export class DatabaseService{
    getService: ()=>string;
}
import {DatabaseService} from "./abstract-parent-service";

export class HibernateService implements DatabaseService{
  constructor() { }
  getService() {
    return "i am hibernate";
  }
}
import {DatabaseService} from "./abstract-parent-service";

export class JDBCService implements DatabaseService{
  constructor() { }
  getService() {
    return "i am Jdbc";
  }
}
//hibernate.service.ts

export class DatabaseService{
    getService: ()=>string;
}
import {DatabaseService} from "./abstract-parent-service";

export class HibernateService implements DatabaseService{
  constructor() { }
  getService() {
    return "i am hibernate";
  }
}
import {DatabaseService} from "./abstract-parent-service";

export class JDBCService implements DatabaseService{
  constructor() { }
  getService() {
    return "i am Jdbc";
  }
}
//jdbc.service.ts

export class DatabaseService{
    getService: ()=>string;
}
import {DatabaseService} from "./abstract-parent-service";

export class HibernateService implements DatabaseService{
  constructor() { }
  getService() {
    return "i am hibernate";
  }
}
import {DatabaseService} from "./abstract-parent-service";

export class JDBCService implements DatabaseService{
  constructor() { }
  getService() {
    return "i am Jdbc";
  }
}
//cmp-a.component.ts

import {DatabaseService} from "./abstract-parent-service";
import {HibernateService} from "./hibernate.service";

@Component({
    selector: 'cmp-a',
    template: `<h1>Hello Hibernate</h1>`,
    providers: [{provide: DatabaseService, useClass: HibernateService}]
})
export class CmpAComponent {
    constructor (private databaseService: DatabaseService) {
        console.log("Database implementation in CompA :"+this.databaseService.getService());
    }
}
import {DatabaseService} from "./abstract-parent-service";
import {HibernateService} from "./hibernate.service";

@Component({
    selector: 'cmp-b',
    template: `<h1>Hello Jdbc</h1>`,
    providers: [{provide: DatabaseService, useClass: JDBCService}]
})
export class CmpAComponent {
    constructor (private databaseService: DatabaseService) {
        console.log("Database implementation in CompA :"+this.databaseService.getService());
    }
}

如果您将此模式用于DI,请确保您的子类服务将来不会扩展任何其他功能。

为什么
new OpaqueToken(“LoginService”)
getting passed
LoginService
而不是
ILoginService
?@DannyBullis未通过LoginService使用,这里要做的是创建一个OpaqueToken,并传递一个值,稍后在构造函数中请求OpaqueToken时使用该值。这只是一个示例字符串。请注意,OpaqueToken已被弃用,应使用InjectionToken。更多的了解可以在这里找到