programing

인터페이스에 클래스 바인딩

powerit 2023. 7. 2. 21:06
반응형

인터페이스에 클래스 바인딩

타이프스크립트를 사용하여 클래스를 쉽게 바인딩할 수 있습니다.

bootstrap(MyAppComponent, [MyClass]);

그러나 다음과 같은 인터페이스에 클래스를 바인딩하고 싶습니다.

boostrap(MyAppComponent, [???]);

다음과 같이 주입할 수 있습니다.

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

Angular2에서 이것이 가능합니까?그렇다면 바인딩을 지정하려면 어떻게 해야 합니까?

간단히 말해서, 문제는 유형 스크립트가 컴파일될 때 인터페이스가 사라진다는 것입니다.따라서 문자열과 함께 @Inject를 사용해야 합니다.

또는 다른 옵션이 있습니다. Victor Savkin의 마지막 기사를 확인하면 댓글에서 다음을 찾을 수 있습니다.

어떤 배경.TypeScript에서 인터페이스는 구조적이며 런타임에 유지되지 않습니다.따라서 다음과 같이 ILoginService를 사용해야 합니다.

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

당신은 문자열을 사용할 필요가 없습니다. 어떤 객체라도 전달할 수 있습니다.우리는 실제로 이러한 목적으로 사용할 수 있는 OpaqueToken이라는 객체를 제공합니다.

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

다음과 같이 사용할 수 있습니다.

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

인터페이스는 런타임에 사용할 수 없기 때문에 인터페이스로 가능한지 모르겠습니다(javascript는 인터페이스에 대해 모릅니다).하지만 추상적인 수업을 이용해서 할 수 있습니다.

//sys-parent-service.ts

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

//확인합니다.service.ts

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

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

//jdbc.service.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());
    }
}

그러나 이 구현의 문제는 HibernateService이고 JDBCService는 이미 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");
    }
}

DI에 이 패턴을 사용하는 경우 하위 클래스 서비스가 이후에 다른 기능을 확장하지 않는지 확인합니다.

언급URL : https://stackoverflow.com/questions/32254952/binding-a-class-to-an-interface

반응형