Saltar al contenido

Inyección de herencia y dependencia

Te sugerimos que pruebes esta respuesta en un ambiente controlado antes de enviarlo a producción, un saludo.

Solución:

Podría resolver esto inyectando MyService dentro de todos y cada uno de los componentes y usar ese argumento para la llamada super() pero eso definitivamente es una especie de absurdo.

No es absurdo. Así es como funcionan los constructores y la inyección de constructores.

Cada clase inyectable tiene que declarar las dependencias como parámetros del constructor y si la superclase también tiene dependencias, estas también deben enumerarse en el constructor de la subclase y pasarse a la superclase con el super(dep1, dep2) llamar.

Pasar un inyector y adquirir dependencias de manera imperativa tiene serias desventajas.

Oculta las dependencias, lo que hace que el código sea más difícil de leer.
Viola las expectativas de alguien familiarizado con el funcionamiento de Angular2 DI.
Rompe la compilación fuera de línea que genera static código para reemplazar DI declarativo e imperativo para mejorar el rendimiento y reducir el tamaño del código.

La solución actualizada evita que se generen varias instancias de myService mediante el inyector global.

import Injector from '@angular/core';
import MyServiceA from './myServiceA';
import MyServiceB from './myServiceB';
import MyServiceC from './myServiceC';

export class AbstractComponent 
  protected myServiceA:MyServiceA;
  protected myServiceB:MyServiceB;
  protected myServiceC:MyServiceC;

  constructor(injector: Injector) 
    this.settingsServiceA = injector.get(MyServiceA);
    this.settingsServiceB = injector.get(MyServiceB);
    this.settingsServiceB = injector.get(MyServiceC);
  


export MyComponent extends AbstractComponent 
  constructor(
    private anotherService: AnotherService,
    injector: Injector
  ) 
    super(injector);

    this.myServiceA.JustCallSomeMethod();
    this.myServiceB.JustCallAnotherMethod();
    this.myServiceC.JustOneMoreMethod();
  

Esto asegurará que MyService se pueda usar dentro de cualquier clase que amplíe AbstractComponent sin la necesidad de inyectar MyService en cada clase derivada.

Esta solución tiene algunas desventajas (consulte el comentario de @Günter Zöchbauer debajo de mi pregunta original):

  • Inyectar el inyector global es solo una mejora cuando hay varios servicios diferentes que deben inyectarse en muchos lugares. Si solo tiene un servicio compartido, probablemente sea mejor/más fácil inyectar ese servicio dentro de las clases derivadas.
  • Mi solución y su alternativa propuesta tienen la desventaja de que dificultan ver qué clase depende de qué servicio.

Para obtener una explicación muy bien escrita de la inyección de dependencia en Angular2, consulte esta publicación de blog que me ayudó mucho a resolver el problema: http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular- 2.html

En lugar de inyectar todos los servicios manualmente, creé una clase que proporciona los servicios, por ejemplo, se inyectan los servicios. Esta clase luego se inyecta en las clases derivadas y se pasa a la clase base.

Clase derivada:

@Component(
    ...
    providers: [ProviderService]
)
export class DerivedComponent extends BaseComponent 
    constructor(protected providerService: ProviderService) 
        super(providerService);
    

Clase básica:

export class BaseComponent 
    constructor(protected providerService: ProviderService) 
        // do something with providerService
    

Clase proveedora de servicios:

@Injectable()
export class ProviderService 
    constructor(private _apiService: ApiService, private _authService: AuthService) 
    

Valoraciones y reseñas

Si te animas, tienes la habilidad dejar una reseña acerca de qué le añadirías a este tutorial.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *