Enlazar una clase a una interfaz


Usando typescript, puedo enlazar fácilmente clases a sí mismas:

bootstrap(MyAppComponent, [MyClass]);

Sin Embargo, me gustaría enlazar mi clase a una interfaz, tales como:

boostrap(MyAppComponent, [???]);

Tal que puedo inyectarlo de la siguiente manera:

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

¿Es esto posible en Angular2? En caso afirmativo, ¿cómo tengo que especificar el enlace?

Author: Wai Ha Lee, 2015-08-27

2 answers

Para abreviar el problema es que las interfaces desaparecen cuando se compila typescript. Así que tendrías que usar @Inject con una cadena.

O hay otra opción, si revisas el último artículo de Victor Savkin puedes encontrar esto en los comentarios :

Algunos antecedentes. En TypeScript, las interfaces son estructurales y no se conservan en tiempo de ejecución. Así que tienes que usar ILoginService de la siguiente manera:

constructor(@Inject("ILoginService") s:ILoginService).

No tienes que usar una cadena-any el objeto se puede pasar allí. En realidad, proporcionamos un objeto llamado OpaqueToken que se puede utilizar para este propósito.

interface ILoginService { login(credentials);}
const ILoginService = new OpaqueToken("LoginService");

Se puede usar así:

constructor(@Inject(ILoginService) s:ILoginService).
 25
Author: Arnaud Boeglin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-15 06:25:01

No sé si es posible con interfaz ya que la interfaz no estará disponible en tiempo de ejecución (javascript no sabe acerca de la interfaz). Pero se puede hacer usando clases abstractas.

//abstract-parent-service.ts

export class DatabaseService{
    getService: ()=>string;
}

//hibernar.Servicio.ts

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

export class HibernateService implements DatabaseService{
  constructor() { }
  getService() {
    return "i am hibernate";
  }
}

//jdbc.Servicio.ts

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());
    }
}

/ / cmp-b.component.ts

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());
    }
}

Pero el problema con esta implementación es HibernateService y JDBCService no son capaces para extender cualquier otra clase ahora porque ya se han casado con DatabaseService.

class A{
    constructor(){
        console.log("in A");
    }
}
class B extends A{
    constructor(){
        super();
        console.log("in B");
    }
}
class C extends A{
    constructor(){
        super();
        console.log("in C");
    }
}
let c = new C();

//This thing is not possible in typescript
class D extends B, C{//error:  Classes can only extend a single class
    constructor(){
        super();// which constructor B or C
        console.log("in D");
    }
}

Si está utilizando este patrón para DI, asegúrese de que sus servicios de clase hijo no van a extender ninguna otra funcionalidad en el futuro.

 7
Author: Arun Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-16 07:44:01