¿Qué se puede poner en el mecanismo de inyección de dependencia en Angular?

Casi todos los desarrolladores de Angular pueden encontrar una solución a su problema en Dependency Injection. Esto se vio claramente en los comentarios de mi último artículo . Las personas consideraron varias opciones para trabajar con datos de DI y compararon su conveniencia para una situación particular. Esto es genial porque una herramienta tan simple nos brinda muchas posibilidades.



Pero varias personas cancelaron mi suscripción porque les resulta difícil comprender DI y sus capacidades en Angular. No hay tantos materiales en Internet sobre cómo usar DI de manera efectiva, y para muchos desarrolladores se trata de trabajar con servicios globales o pasar datos globales desde la raíz de la aplicación a los componentes.



Echemos un vistazo más profundo a este mecanismo en Angular.









¿Conoces tus adicciones?



A veces no es fácil comprender cuántas dependencias tiene su código.



Por ejemplo, eche un vistazo a esta pseudoclase y cuente cuántas dependencias tiene:



import { API_URL } from '../../../env/api-url';
import { Logger } from '../../services/logger';
 
class PseudoClass {
   request() {
       fetch(API_URL).then(...);
   }
 
   onError(error) {
       const logger = new Logger();
 
       logger.log(document.location, error);
   }
}


Responder
fetch — API, , , .



API_URL — ( ).



new Logger() — , .



document — API .





¿Así que qué hay de malo?



Por ejemplo, esta clase es difícil de probar porque depende de datos importados de otros archivos y entidades específicas en ellos.



Otra situación: el documento y la recuperación funcionarán sin problemas en su navegador. Pero si un día necesita transferir la aplicación a la representación del lado del servidor, es posible que las variables globales necesarias no estén en el entorno de nodejs.



Entonces, ¿qué es DI y por qué se necesita?



Dependency Injection gestiona las dependencias dentro de una aplicación. Básicamente, para nosotros, como desarrolladores de Angular, este sistema es bastante simple. Hay dos operaciones principales: poner algo en el árbol de dependencias u obtener algo de él.



Para obtener una perspectiva más teórica sobre DI, lea sobre el principio de inversión de control . También puede ver videos interesantes sobre el tema: una serie de videos sobre IoC y DI de Ilya Klimov en ruso o un video corto sobre IoC en inglés.



Toda la magia proviene del orden en que suministramos y tomamos las dependencias.



Cómo funcionan los ámbitos en DI:





¿Qué podemos poner en DI?



La primera de las operaciones DI es poner algo en ella. En realidad, para esto, Angular nos permite escribir la matriz de proveedores en los decoradores de nuestros módulos, componentes o directivas. Veamos en qué puede consistir esta matriz.



Proporcionar clase



Por lo general, todos los desarrolladores de Angular lo saben. Esto es cuando agrega un servicio a su aplicación.



Angular crea una instancia de la clase cuando la solicita por primera vez. Y con Angular 6, no podemos escribir clases en la matriz de proveedores, pero decirle a la clase en qué parte de la DI debe ir con provideIn :



providers: [
   {
       provide: SomeService,
       useClass: SomeService
   },
   // Angular        :
   SomeService
]




Aportando valores



Los valores constantes también se pueden suministrar a través de DI. Puede ser una cadena simple con la URL de su API o un Observable complejo con datos.



La provisión de valores generalmente se implementa junto con un InjectionToken . Este objeto es la clave del motor DI. Primero, dice: "Quiero obtener estos datos para esta clave". Y luego vienes a DI y preguntas: "¿Hay algo en esta tecla?"



Bueno, un caso común es el reenvío de datos globales desde la raíz de la aplicación.



Es mejor ver esto en acción de inmediato, así que echemos un vistazo a stackblitz con un ejemplo:



Expandir ejemplo






Entonces, en el ejemplo, obtuvimos la dependencia de DI en lugar de importarla como una constante desde otro archivo directamente. ¿Y por qué es mejor para nosotros?



  • Podemos anular el valor del token en cualquier nivel del árbol DI sin cambiar los componentes que lo usan.
  • Podemos burlarnos del valor del token con los datos apropiados al realizar la prueba.
  • El componente está completamente aislado y siempre funcionará igual independientemente del contexto.




Proporcionar fábricas



En mi opinión, esta es la herramienta más poderosa en el motor de inyección de dependencia de Angular.



Puede crear un token que será el resultado de combinar y convertir los valores de otros tokens.



Aquí hay otro stackbitz con un ejemplo detallado de cómo crear una fábrica con un flujo.



Expandir ejemplo






Puede encontrar muchos casos en los que proporcionar una fábrica ahorra tiempo o hace que el código sea más legible. A veces inyectamos dependencias en componentes solo por combinarlos o transformarlos en un formato completamente diferente. En el artículo anterior, analicé este problema con más detalle y mostré un enfoque alternativo para resolver tales situaciones.



Proporcionar una instancia existente



No es un caso común, pero esta opción puede ser una herramienta muy útil.



Puede poner una entidad que ya ha sido creada en el token. Funciona bien con forwardRef .



Mire otro ejemplo de stackblitz con una directiva que implementa la interfaz y reemplaza otro token con useExisting. En este ejemplo, queremos anular el valor del token de solo DI para los componentes secundarios del elemento al que se cuelga la directiva. Además, la directiva puede ser cualquiera; lo principal es que implementa la interfaz requerida.



Expandir ejemplo






Trucos DI Decorator



Los decoradores DI le permiten hacer que las consultas DI sean más flexibles.



Si no conoce a los cuatro decoradores, le recomiendo leer este artículo en Medium . El artículo está en inglés, pero hay visualizaciones muy interesantes y comprensibles sobre el tema.



No mucha gente también sabe que los decoradores DI se pueden usar en la matriz deps, que prepara los argumentos para la fábrica de proveedores.




providers: [
   {
     provide: SOME_TOKEN,
     /**
      *     ,  
      * [new Decorator(), new Decorator(),..., TOKEN]
      * .
      *
      *      ‘null’,     
      * OPTIONAL_TOKEN
      */
     deps: [[new Optional(), OPTIONAL_TOKEN]],
     useFactory: someTokenFactory
   }
 ]




Fábrica de tokens



El constructor InjectionToken toma dos argumentos.



El segundo argumento es un objeto con una configuración de token.



Una fábrica de tokens es una función que se llama en el momento en que alguien solicita este token por primera vez. En él, puede calcular un cierto valor estándar para el token o incluso acceder a otras entidades DI a través de la función de inyección.



Eche un vistazo a un ejemplo de la implementación de la funcionalidad de flujo de clics de botón, pero esta vez en la fábrica de tokens.



Expandir ejemplo






Conclusión



DI en Angular es un tema asombroso: a primera vista, no hay muchas palancas y herramientas diferentes para aprender, pero puedes escribir y hablar durante horas sobre las posibilidades y usos que nos dan.



Espero que este artículo le haya proporcionado una base desde la que pueda encontrar sus propias soluciones para simplificar el trabajo con datos en sus aplicaciones y bibliotecas.



All Articles