Saludos,
Francisco
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:
¿Listo para poner esto en práctica? Continuemos
Clase 1
Actualizar a Angular 6
Clase 2
Servicios en Angular
Clase 3
Crear tu propio servicio
Clase 4
Consultas asíncronas
Clase 5
Inyector de dependencias en Angular
Clase 6
Compartir datos de un servicio
Clase 7
Programación reactiva
Clase 8
El patrón del observable
Clase 9
Observadores y Observables en RxJS
Clase 10
Operadores en RxJS
Clase 11
Async Pipe
Clase 12
Operador de navegación segura ?.
Clase 13
Async y suscripciones a un Observable
Clase 14
Servicios en Angular 6
2 comentario(s)