Angular — Dependency Inversion

La idea es poder desacoplar todos esos servicios externos que utilizamos y que resulte sencillo cambiar sus implementaciones sin hacer cambios drásticos en nuestros componentes.

Vamos al ejemplo, sencillo pero sustancioso.


Definiendo clases:

export abstract class Writer {
  abstract write: (text: string) => string;
}

Creamos las implementaciones y definimos detalles, es un ejemplo sencillo, pero se logra entender la idea.

class WriterUpper extends Writer {
  write = (text: string): string => {
    return text.toUpperCase();
  };
}
class WriterLower extends Writer {
  write = (text: string): string => {
    return text.toLowerCase();
  };
}

Lo siguiente que debemos hacer es utilizar la inyección de dependencias de angular para definir la implementación que se instanciara cuando hagamos referencia a la clase Writer.

providers: [
  {
    provide: Writer,
    useClass: WriterUpper,
  },
];

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

export abstract class Writer {
  abstract write: (text: string) => string;
}
class WriterUpper extends Writer {
  write = (text: string): string => {
    return text.toUpperCase();
  };
}
class WriterLower extends Writer {
  write = (text: string): string => {
    return text.toLowerCase();
  };
}
@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [
    {
      provide: Writer,
      useClass: WriterUpper,
    },
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

Listo, tenemos todo lo necesario, vamos al componente.

app.component.ts

export class AppComponent {
  title = 'Dependency Inversion';
  constructor(private writer: Writer) {
    this.title = this.writer.write(this.title);
  }
}

app.component.html

<h1>{{title}}</h1>
providers:[{
    provide: Writer,
    useClass: WriterLower,
}],