Sử dung Dependency Injection trong Angular

Giới thiệu nội dung bài viết

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?

1. Dependency Injection là gì

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

2. Dependency Injection Framework

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 dependecy 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){
}

2. Nhúng 1 Service vào 1 Service khác

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.

  • Chúng ta tạo Logger Service
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 dạng 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.

  • Chúng ta tạo lớp ProductService
1
2
@Injectable()
export class ProductService{}
  • Trong constructor của ProductService chúng ta nhúng LogService vào
1
2
3
constructor(private loggerService: LoggerService) {
    this.loggerService.log("Product Service Constructed");
}
  • Chúng ta cập nhật phương thức getProduct của ProductService
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]
})

3. Sử dụng ngModule để đăng ký dependency

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 dependecy đượ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],

Mọi người hãy subcribe kênh youtube dưới đây nhé. Videos về các kỹ năng mềm và lập trình sẽ được cập nhật hằng tuần


Comments