Inject an Interface with Angular 4

Viewed 6129

I'm trying to create a generic DeleteableConfirmationComponent that will allow me to show a confirmation dialog and invoke the delete method from any injected service implementing a Deleteable infterface.

To do so, I've created this Interface:

export interface Deleteable {
  delete(object);
}

and I have a service that implements it:

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

For the DeleteableConfirmationComponent, I've tried to inject the service using constructor:

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

but unfortunately, I've got an error saying it can't resolve all parameters for DeleteableConfirmationComponent.

For now, I'm using the dialog data options, in order to pass my service:

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

but it feels dirty and does allow any kind of service to be injected while I want to force service that implement the Deleteable interface.

I was thinking I could probably be better going with an abstract class but I'm more a fan of composition over inheritance.

Any idea or best practice advise?

2 Answers

It is possible with InjectionToken a replacement for the deprecated 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
  ) {}
Related