Chào các bạn,hôm nay anh sẽ hướng dẫn mọi người về Dependency Injection là như thế nào?
Dependency Injection là một phần quan trọng trong bộ core của Angular. Sử dụng cơ chế Dependency Injection giúp chúng ta có thể nhúng service vào các component hoặc các service với nhau.
Như ta thấy ở ví dụ bài Service. Ta nhúng Service vào Component bằng cách tạo new đối tượng ProductService trong constructor như sau:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { Component } from '@angular/core';
import { ProductService } from './product.service';
import { Product } from './product';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent
{
products:Product[];
productService;
constructor(){
this.productService=new ProductService();
}
getProducts() {
this.products=this.productService.getProducts();
}
}
Cách này có rất nhiều hạn chế mà anh nêu lên trong phần cuối của bài Service và thực tế thì không ai dùng cả. Như vậy ta phải thay đổi cách nhúng ServiceProduct vào Component theo cơ chế Dependency Injection
Có 5 thành phần chính trong Angular Dependency Injection Framework
Consumer : nơi mà nhúng service vào. Trong ví dụ của chúng ta là AppComponent
Dependency : Những service được nhúng vào component
DI Token : Được sinh ra là một dãy ký tự tượng trưng cho ID và là duy nhất khi Service đăng ký là Dependency Injection với Framework
Provider : quản lý danh sách các dependencies và token của nó
Injector : quản lý việc nhúng các đối tượng Dependency vào các consumer
Cơ chế hoạt động của Dependency như sau:
Dependency đăng ký với Provider
Sau đó Angular Provider sẽ nhúng các dependency vào các module consumer tương ứng.
Consumer sẽ khởi tạo các đối tượng Dependency thông qua constructor.
Chúng ta sẽ viết lại ví dụ ProductService ở trên bằng cách sử dụng DI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { Component } from '@angular/core';
import { ProductService } from './product.service';
import { Product } from './product';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
providers: [ProductService]
})
export class AppComponent
{
products:Product[];
constructor(private productService:ProductService){
}
getProducts() {
this.products=this.productService.getProducts();
}
}
Chúng ta sẽ thêm thẻ provider trong @Component
1
providers: [ProductService]
Trong Constructor chúng ta không tạo new đối tượng nữa và dùng
1
2
constructor(private productService:ProductService){
}
Trong ví dụ dưới đây ta sẽ nhúng Service Log vào Service Product. Service Log chỉ làm nhiệm vụ ghi log.
1
2
3
4
5
6
7
8
import { Injectable } from '@angular/core';
@Injectable()
export class LoggerService {
log(message:any) {
console.log(message);
}
}
Chúng ta sử dụng @Injectable cho những service nào mà chúng ta có ý định nhúng vào. Đây như một quy định chung cho các service để chúng ta có thể phân biệt mục đích của các class.
1
2
@Injectable()
export class ProductService{}
1
2
3
constructor(private loggerService: LoggerService) {
this.loggerService.log("Product Service Constructed");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public getProducts() {
this.loggerService.log("getProducts called");
let products:Product[];
products=[
new Product(1,'Memory Card',500),
new Product(1,'Pen Drive',750),
new Product(1,'Power Bank',100)
]
this.loggerService.log(products);
return products;
}
Cuối cùng chúng ta đăng ký Service Log và Product trong AppComponent
1
2
3
4
5
6
7
8
9
10
import { Component } from '@angular/core';
import { ProductService } from './product.service';
import { Product } from './product';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
providers: [ProductService,LoggerService]
})
Ngoài cách đăng ký service trong thuộc tính providers trong Component. Chúng ta có thể đăng ký trong ngModule.
Để đảm bảo dependency được nhúng vào toàn bộ ứng dụng Angular, chúng ta khai Provider ở root module.
Đầu tiên chúng ta xoá thuộc tính provider trong AppComponent
1
2
3
4
5
6
7
8
9
10
import { Component } from '@angular/core';
import { ProductService } from './product.service';
import { Product } from './product';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
Tiếp đến chúng ta khai báo provider trong ngModule của angular
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { ProductService } from './product.service';
import { LoggerService } from './logger.service';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpModule,
FormsModule
],
providers: [ProductService,LoggerService],
bootstrap: [AppComponent]
})
export class AppModule { }
Chúng ta sẽ thấy dòng Provider như sau
1
providers: [ProductService,LoggerService],