Dependency Injection trong angular - Bài 2 - Injector

·

3 min read

1. Khái quát

Angular có 2 cây injector: module injector và element injector. Module injector dùng cho root module và lazy load module, element injector dùng cho DOM element như component và directive. Angular tạo cây Injector khi Application bootstrap. Mỗi lazy load module sẽ có 1 instance injector tiêng nhưng với eagerly module sẽ dùng injector của root module.

image.png

image.png

2. Cấu trúc

  • Module Injector Tree

Node cao nhất của cây này là Null Injector, nếu dependency không được tìm thấy nó sẽ bắn ra lỗi trừ khi dependency là @optional

Node thứ 2 là Platform Injector - chứa các provider dựng sẵn như DomSanitize

Tiếp theo là root injector: nó được tạo ra khi đặt các service được đặt trong providers của @NgModule (@NgModule của root module và các eagerly module) , service được khai báo với decorator @Injectable() với providedIn : root

Sau đấy là các lazy injector : lazy instance injector được tạo ra khi đặt service trong providers của @NgModule của lazy module,service được khai báo với decorator @Injectable() với providedIn : any

  • Element Injector Tree

Node cao nhất là injector của App component - root component, sau root component, mỗi component, directive sẽ có 1 injector, nếu providers của component nào trống thì injector của nó sẽ là 1 empty injector. Khi component bị destroy, injector của nó cũng bị destroy.

3. Hoạt động

Khi 1 component(directive/ pipe) cần 1 dependency, injector của nó (element injector) sẽ tìm kiếm dependency dựa vào token, đầu tiên injector đọc dependency này ở constructor và tìm kiếm nó trong providers của component này.

  • Nếu tìm thấy provider, injector sẽ tạo 1 instance của dependency dựa vào công thức được cung cấp của provider (useValue, useClass, useExisting, useFactory), nếu dependency này đã có 1 instance, injector sẽ lấy instance này mà không cần tạo mới, sau đó inject vào component.
  • Nếu không tìm thấy: injector của component này sẽ hỏi lên parent injector, cứ như vậy đến hết root component ịnector (app component), nếu vẫn không tìm thấy nó sẽ tìm kiếm ở module injector, module đầu tiên tìm kiếm là module chứa component này, rồi cứ như vậy tìm lên module cha ... nó tìm cho tới Null Injector, nếu vẫn không thấy thì sẽ bắn ra lỗi, nếu dependency được khai báo là @Optional thì sẽ không có lỗi.

Lưu ý:

  1. Eagerly module không có injector, nó dùng injector của root module, lazy load module thì có.
  2. Nếu provide service với cùng token ở 2 module eagerly, token import sau sẽ được chọn để lấy dependency
  3. Nếu provide cùng service với 1 root module và 1 Eagerly module, service ở root module sẽ được lấy
  4. Service chỉ là singletons trong scope mà nó được khai báo. Tức nếu khai báo ở providerin: root, nó sẽ có phạm vi toàn app, nếu khai báo trong providers của module, nó sẽ có phạm vi ở module, nếu khai báo ở providers của component, nó chỉ tồn tại trong component đấy.

Tham khảo: tektutorialshub.com/angular/how-dependency-..