9. Servizi
ng generate service
nome-del-servizio
Genera il file
nome-del-servizio.service.
ts
@Injectable()
Metadati per Dependency
Injection
import { Injectable } from '@angular/core' ;
@Injectable()
export class LoggerService {
constructor() { }
}
13. Perchè DI?
Test
Difficile da testare
export class Car {
engine: Engine;
steering: SteeringWheel;
constructor() {
this.engine = new Engine();
this.steering = new SteeringWheel();
}
powerOn() {
this.engine.powerOn();
}
}
14. Perchè DI?
Test
Difficile da testare
Fragile
Non aperta al
cambiamento
export class Car {
engine: Engine;
steering: SteeringWheel;
constructor() {
this.engine = new Engine();
this.steering = new SteeringWheel();
}
powerOn() {
this.engine.powerOn();
}
}
15. Perchè DI?
Test
Difficile da testare
Fragile
Non aperta al
cambiamento
Non flessibile
Legata alla
implementazione
export class Car {
engine: Engine;
steering: SteeringWheel;
constructor() {
this.engine = new Engine();
this.steering = new SteeringWheel();
}
powerOn() {
this.engine.powerOn();
}
}
16. Perchè DI?
Dipendenze nel
costruttore
Passo le dipendenze
Test
Facile da testare
Estendibile
interface al posto di classi
concrete
export class Car {
constructor(
public engine: Engine,
public steering: SteeringWheel
) { }
powerOn() {
this.engine.powerOn();
}
}
17. Perchè DI?
Dipendenze nel
costruttore
Passo le dipendenze
Test
Facile da testare
Estendibile
interface al posto di classi
concrete
export class Car {
constructor(
public engine: Engine,
public steering: SteeringWheel
) { }
powerOn() {
this.engine.powerOn();
}
}
let car = new Car(new Engine(), new SteeringWheel());
18. Perchè DI?
Factory pattern
Crea istanze di Car
export class CarFactory {
createCar() {
return new Car(
this.createEngine(),
this.createSteeringWheel()
);
}
createEngine() {
return new Engine();
}
createSteeringWheel() {
return new SteeringWheel();
}
}
let car = new CarFactory().createCar();
19. Perchè DI?
Factory pattern
Crea istanze di Car
Code Smell
La classe factory può
evolvere velocemente
export class CarFactory {
createCar() {
return new Car(
this.createEngine(),
this.createSteeringWheel()
);
}
createEngine() {
return new Engine();
}
createSteeringWheel() {
return new SteeringWheel();
}
}
let car = new CarFactory().createCar();
20. Perchè DI?
Factory pattern
Crea istanze di Car
Code Smell
La classe factory può
evolvere velocemente
DI
Chiedo al container una
istanza di Car
let car = container.get(Car);
22. Dependency Injection
Dependency Injection Gerarchica
Tree model, Injector bubbling
Service Provider
Component vs ngModule
Singleton
Una istanza per scope
Testabilità
23. Dependency
Injection
Creare un service
import { Injectable } from '@angular/core';
@Injectable()
export class LoggerService {
constructor() { }
log(msg: any) { console.log(msg); }
error(msg: any) { console.error(msg); }
warn(msg: any) { console.warn(msg); }
}
27. Challenge - Servizi
● Andiamo su https://stackblitz.com/edit/aw-services-challenge
● Creare un nuovo servizio con nome Api nella cartella app. Il servizio dovrà implementare le chiamate
alle API per otterene i dati e effettuare l’upvote.
● Importare il database nel servizio
● Definire il metodo pubblico getLinks(page: number) nel servizio creato. Dovrà restituire i Link dal
database
● Rimuovere DATABASE da link-list.component.ts, istanziare il servizio e utilizzare il metodo getLinks
● Definire il metodo pubblico upvote(id: number) nel servizio. Dovrà implementare la logica di upvoted,
definita in link-list.component.ts
● Istanziare il servizio e utilizzare il metodo upvote, ridefinendo l'implementazione di upvote in
link-item.component.ts. Eliminare la proprietà upvoted di tipo EventEmitter in questo componente
28. Challenge - DI
● Andiamo su https://stackblitz.com/edit/aw-di-challenge
● Aggiungere il provider per ApiService in app.module.ts
● Iniettare il servizio ApiService nel costruttore dei componenti che lo utilizzano. Rimuovere
l'istanziazione di ApiService, sostituendola con il servizio iniettato
● Creare un nuovo servizio con nome Logger
● Implementare in LoggerService la proprietà privata counter
● Implementare in LoggerService le seguenti funzioni. Ogni funzione deve incrementare la proprietà
counter, stampare il valore di counter e del messaggio
○ log(e)
○ warn(e)
○ error(e)
● Definire il provider di LoggerService nel decoratore @NgModule
● Iniettare il servizio LoggerService nel costruttore dei componenti
● Utilizzare la funzione log di LoggerService nei metodi changePage e upvote definiti nei component
29. Challenge - DI
● Sperimenta! Definire il provider di LoggerService nel decoratore @Component in uno due
componenti. Cosa accade?