El patrón de la inyección de dependencias es parte fundamental del funcionamiento y desarrollo de una aplicación de Angular, por lo que es muy importante que aprendas el por qué del inyector.
Considera el siguiente objeto:
class Article{
constructor(){
this.user = new User();
this.image = new Image();
}
}
¿Cuál es el problema de este nuevo objeto? Bueno, su principal problema es que el objeto Article se encarga de la construcción de sus propias dependencias y eso trae algunos problemas. Primero, la construcción de tu objeto (Article), depende de la construcción de sus dependencias (User, Image). Si por alguna razón la firma de la clase User cambiará y tuvieras que crear el objeto con un username como argumento, tendrías también que cambiar el constructor de Article.
Segundo, tu objeto Article es difícil de probar usando pruebas unitarias. Un objeto fácil de probar es independiente y no necesita de otros objetos para poder funcionar, este no es el caso de Article, está “acoplado” con los objetos User e Image. Si algo falla en Image, eso significa que Article fallará también.
Además, tu código es inflexible, si quisieras intercambiar las dependencias de tu objeto, no podrías hacerlo, porque estás están incrustadas directamente en el funcionamiento de Article.
Importante también, si quisieras usar la misma Imagen para varios objetos Article, no podrías, porque al construir un objeto Article, automáticamente construyes un nuevo objeto Image.
Afortunadamente, mejorar esta versión de tu código es muy fácil, sólo deberías cambiar el objeto Article a funcionar así:
class Article{
constructor(private user : User, private image: Image){}
}
Recuerda que lo anterior es una forma en cómo podemos especificar e inicializar los atributos de un objeto en Typescript, dicho código es similar al siguiente:
class Article{
private user : User;
private image : Image
constructor(user : User, image : Image){
this.image = image;
this.user = user;
}
}
Lo que es importante acerca del nuevo cambio, es que ahora en lugar de crear las dependencias en el contructor de nuestro objeto, optamos mejor por recibirlas como argumento al momento de crear el objeto:
new Article(new User(), new Image());
Esto hace nuestro código mucho más flexible y fácil de probar. Además, lo hace independiente de los otros dos objetos y de su funcionamiento interno.
Así es como precisamente funcionan nuestros componentes y servicios en Angular. No nos encargamos de crear las dependencias, más bien las recibimos… ¿pero las recibimos de quién? Del inyector de dependencias.
Particularmente, quienes se encargan (sí, en plural) de entregar las dependencias de nuestros componentes son los inyectores de Angular. El framework mismo se encarga de construir los inyectores que tu aplicación necesite.
¿Cómo es que un inyector sabe qué debe inyectar? Bueno, para eso usa por un lado, la información que está en el arreglo providers de un módulo, y el tipo de objeto solicitado.
Para que el inyector sepa que debe encargarse de una dependencia y sepa cómo cumplir con la construcción de dicha dependencia, debemos especificar la dependencia en el arreglo providers de nuestro módulo:
@NgModule({
providers: [ArticlesService]
})
Angular sabe qué provider debe usar para satisfacer una dependencia, utilizando algo que se conoce como los Injector Tokens. Los injector tokens son los que aparecen como tipo de los argumentos en el constructor de un componente o servicio que requiera que el inyector cree sus dependencias:
@Component({})
class Ejemplo{
// En este ejemp. User es el injector token
constructor(private user : User){}
}
Una vez que uno de los inyectores encuentra este token, busca en los providers uno que sirva para esa dependencia. Como en el siguiente ejemplo
@NgModule({
providers: [User]
})
En la sintaxis más simple de un provider, el nombre de la clase funciona como el token injector para dicha dependencia, eso quiere decir que si especificamos la clase User en providers, al encontrar el injector token User, se usará dicha clase para crear un nuevo objeto que se envíe como dependencia.
Es posible que, además, especifiquemos un token personalizado, así:
@NgModule({
providers: [{ provide: SuperUser, useClass: User}]]
})
En este nuevo ejemplo, el token injector es SuperUser, y la clase para satisfacer dicha dependencia es User.
Esa esa la razón por la que:
- Tus servicios se decoran con la función @Injector
- Los servicios deben ser especificados en el arreglo providers de un módulo.
¿Listo para poner esto en práctica? Continuemos
-
check_circle_outlineMódulo 1 | 7 clases
Introducción
expand_more -
check_circle_outlineMódulo 2 | 9 clases
Primeros pasos con Angular
expand_more -
check_circle_outlineMódulo 3 | 21 clases
Componentes a detalle
expand_more -
check_circle_outlineMódulo 4 | 14 clases
Servicios y Observadores
expand_more-
done_all
Clase 1
Actualizar a Angular 6
-
done_all
Clase 2
Servicios en Angular
-
done_all
Clase 3
Crear tu propio servicio
-
done_all
Clase 4
Consultas asíncronas
-
done_all
Clase 5
Inyector de dependencias en Angular
-
done_all
Clase 6
Compartir datos de un servicio
-
done_all
Clase 7
Programación reactiva
-
done_all
Clase 8
El patrón del observable
-
done_all
Clase 9
Observadores y Observables en RxJS
-
done_all
Clase 10
Operadores en RxJS
-
done_all
Clase 11
Async Pipe
-
done_all
Clase 12
Operador de navegación segura ?.
-
done_all
Clase 13
Async y suscripciones a un Observable
-
done_all
Clase 14
Servicios en Angular 6
-
-
check_circle_outlineMódulo 5 | 7 clases
Animaciones
expand_more -
check_circle_outlineMódulo 6 | 2 clases
Cierre del curso
expand_more