使用 Angular 4 注入接口



我正在尝试创建一个通用DeleteableConfirmationComponent,该将允许我显示确认对话框并从实现Deleteableinfterface的任何注入服务中调用delete方法。

为此,我创建了此接口:

export interface Deleteable {
delete(object);
}

我有一个实现它的服务:

@Injectable()
export class LocalityService implements Deleteable {
delete(locality): Observable<Locality> {
// Delete logic.
}
}

对于DeleteableConfirmationComponent,我尝试使用构造函数注入服务:

export class DeleteableConfirmationComponent {
constructor(
public dialog: MdDialogRef<DeleteableConfirmationComponent>,
@Inject(MD_DIALOG_DATA) public data: any,
private service: Deleteable
) {}
delete() {
this.service.delete(this.object)
.subscribe(() => {
this.dialog.close();
});
}
}

但不幸的是,我有一个错误,说它无法解析可删除确认组件的所有参数

现在,我正在使用对话框数据选项,以便传递我的服务:

confirmDelete(locality) {
this.dialog.open(DeleteableConfirmationComponent, {
data: {
service: this.localityService
}
});
}

但它感觉很脏,并且确实允许注入任何类型的服务,而我想强制实现Deleteable接口的服务。

我在想我可能会更好地选择abstract class但我更喜欢作曲而不是继承。

有什么想法或最佳实践建议吗?

如注释中所述,您可以将接口转换为抽象类:

export abstract class Deleteable {
abstract delete(object);
}

然后在您的提供程序中,您可以将其映射到实际类:

providers: [{ provide: Deleteable, useValue: new LocalityService() }]

您可能不喜欢这种方法,因为现在看来LocalityService必须扩展Deleteable。但是,如果LocalityService需要扩展其他类怎么办?不允许多重继承:

// Error: Classes can only extend a single class
export class LocalityService extends OtherClass, Deleteable { }

或者您可能根本不喜欢Deleteable现在将显示在LocalityService的原型链中的事实:

export class LocalityService extends Deleteable {
delete(locality): void {
// Returns true
alert(this instanceof Deleteable);
}
}

但是,如本答案所示,TypeScript 允许您将类视为接口。因此,您可以将implements与抽象类一起使用。

export class LocalityService extends OtherClass implements Deleteable {
delete(locality): void {
// Returns false
alert(this instanceof Deleteable);
}
}

因此,出于所有意图和目的,您的抽象类现在的行为类似于接口。它甚至不会出现在原型链中。

可以通过InjectionToken替换已弃用的OpaqueToken

export const AuthenticationProvider = new InjectionToken(
"AuthenticationProvider",
{ providedIn: "root", factory: () => new CognitoAuthenticationProvider() }
);
...
@Injectable()
export class CognitoAuthenticationProvider implements IAuthenticationProvider {
...
@Injectable({
providedIn: "root"
})
export class AuthenticationService {
constructor(
@Inject(AuthenticationProvider)
private authenticationProvider: IAuthenticationProvider,
private http: HttpClient
) {}

最新更新