最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

typescript nodejs 依賴注入實現(xiàn)方法代碼詳解

 更新時間:2019年07月21日 08:59:09   作者:村長lv  
今天分享的是用typescript語言實現(xiàn)的ioc模式,這邊用到的主要組件是 reflect-metadata 這個組件可以獲取或者設置元數(shù)據(jù)信息,接下來通過本文給大家介紹typescript nodejs 依賴注入實現(xiàn)方法,需要的朋友可以參考下

依賴注入通常也是我們所說的ioc模式,今天分享的是用typescript語言實現(xiàn)的ioc模式,這邊用到的主要組件是 reflect-metadata 這個組件可以獲取或者設置元數(shù)據(jù)信息,它的作用是拿到原數(shù)據(jù)后進行對象創(chuàng)建類似C#中的反射,先看第一段代碼:

import "reflect-metadata";
/**
 * 對象管理器
 */
const _partialContainer = new Map<string, any>();
const PARAMTYPES = "design:paramtypes";//需要反射的原數(shù)據(jù),有很多種選擇,我們這里選擇的是拿到構造函數(shù)的參數(shù)類型,為了后續(xù)判斷
/**
 * 局部注入器,注入的是全局服務,實例是全局共享
 */
export function Inject(): ClassDecorator {
  return target => {
    const params: Array<any> = Reflect.getMetadata(PARAMTYPES, target);
    if (params)
      for (const item of params) {
        if (item === target) throw new Error("不能注入自己");
      }
    _partialContainer.set(target.name, target);//加入到對象管理器中,這個時候對象還沒有被創(chuàng)建
  }
}

   上面的代碼是創(chuàng)建一個類級別的裝飾器,表示凡是使用了這個裝飾器的類都會被依賴注入對象管理器管理,這里沒有馬上創(chuàng)建服務,原因是reflect-metadata的執(zhí)行有先機是最高的,而這個依賴注入是支持手動注入一些實例對象,所有為了防止出現(xiàn)注入?yún)?shù)為undefined所以創(chuàng)建實例的工作是放在后面的,請看接下來的代碼:

/**
 *
 * @param type 已創(chuàng)建的實例對象
 */
export function addServiceInGlobal(...types: Array<Object>) {
  for (const iterator of types) {
    _partialContainer.set(iterator.constructor.name, iterator);
  }
}

 上面的方法是手動注入實例對象時調(diào)用的,我們需要提高這個方法的執(zhí)行優(yōu)先級,具體的實例會在后面演示,接下來是最重要部分,創(chuàng)建實例部分:

export function serviceProvider<T>(service: ServiceType<T>): T {
  if (_partialContainer.has(service.name) && !_partialContainer.get(service.name).name)
    return _partialContainer.get(service.name);// 如果實例已經(jīng)被創(chuàng)建就直接返回
 
  const params: Array<any> = Reflect.getMetadata(PARAMTYPES, service);// 反射拿到構造函數(shù)的參數(shù)類型
  const constrparams = params.map(item => { // 實例化參數(shù)中的依賴
    if (!_partialContainer.has(item.name)) throw new Error(`${item}沒有被注入`);// 如果沒有注入就拋出異常
    if (item.length)// 表示這個類型還有其它依賴
      return serviceProvider(item);// 遞歸繼續(xù)獲取其他依賴
    if (_partialContainer.has(item.name) && !_partialContainer.get(item.name).name)
      return _partialContainer.get(item.name);// 如果實例已經(jīng)被創(chuàng)建就直接返回
    const obj = new item();// 已經(jīng)沒有其他依賴了 開始創(chuàng)建實例
    _partialContainer.set(item.name, obj);// 替換對象管理器中原來沒有實例化的對象
    return obj;
  });
  const obj = new service(...constrparams); // 這里表示對象沒有被創(chuàng)建,開始創(chuàng)建對象
  _partialContainer.set(service.name, obj);// 替換對象管理器中原來沒有實例化的對象
  return obj;
}

 上面代碼寫的稍微有一點點復雜,其他理解起來也不困難,大白話講就是 如果已經(jīng)實例化了直接返回實例不然就開始對象以及創(chuàng)建出所有的依賴。接下來是例子:

import { serviceProvider, addServiceInGlobal, Inject } from './core/injectable/injector';
import "reflect-metadata";
import moment = require('moment');
@Inject()
export class ServiceA{
  property?:string;
  msg(){
    return "ServiceA";
  }
}
@Inject()
export class ServiceC {
  constructor(private service: ServiceA) { }
  print() {
   console.log( this.service.property);
    return "調(diào)用了我";
  }
}
@Inject()
export class ServiceD{
  print(){
   console.log("我在測試注入");
  }
}
@Inject()
export class GlobalService {
  constructor(private service: ServiceC) { }
  msg!: string;
  print() {
    console.log(`共享模塊${this.service.print()}`)
  }
}
@Inject()
export class Init {
  constructor(private service: ServiceA,
    private serviceD: ServiceD,
    private global: GlobalService,
    private date: Date,
    private strList: string[],
    private serviceC: ServiceC,
  ) { }
  start() {
    console.log(this.service.msg());
    this.service.property = "A模塊設置的共享數(shù)據(jù)"
    console.log(moment(this.date).format("YYYY-MM-DD"))
    console.log(this.strList);
    this.serviceD.print();
    this.serviceC.print();
    this.global.print();
  }
}
 
const obj = new Date("2017-1-1");
const str = ['呂順彬','菜鳥','豆豆','大鐵','CC哥','碼農(nóng)之家的一群人'];
addServiceInGlobal(obj, str); // 添加手動創(chuàng)建的實例對象到對象管理器
const service = serviceProvider(Init); // 開始創(chuàng)建實例
service.start()// 執(zhí)行

上面的實例中得到一下執(zhí)行結果:

總結:上面我用的是默認全局注入,沒有做singletion (單例) ,如果要做的話稍微修改下代碼就可以實現(xiàn),這里邊的難點可能是基于反射的設計方法,如果前端思維可能理解起來稍微困難點,后臺的話稍微好點。

總結

以上所述是小編給大家介紹的typescript nodejs 依賴注入實現(xiàn)方法代碼詳解,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!

相關文章

  • 前端包管理器npm、Yarn和pnpm的超全面比較

    前端包管理器npm、Yarn和pnpm的超全面比較

    NPM(Node Package Manager)是Node.js默認的包管理器,這篇文章主要給大家介紹了關于前端包管理器npm、Yarn和pnpm的超全面比較,文中介紹的非常詳細,需要的朋友可以參考下
    2024-09-09
  • Node.js中MongoDB查詢數(shù)據(jù)的方法

    Node.js中MongoDB查詢數(shù)據(jù)的方法

    在Node.js中,可以使用MongoDB驅動程序和Mongoose庫來進行MongoDB的查詢操作,本文就來介紹一下Node.js中MongoDB查詢數(shù)據(jù)的方法,感興趣的可以了解一下
    2023-12-12
  • Node.js API詳解之 util模塊用法實例分析

    Node.js API詳解之 util模塊用法實例分析

    這篇文章主要介紹了Node.js API詳解之 util模塊用法,結合實例形式分析了node.js API中util模塊基本功能與相關函數(shù)使用技巧,需要的朋友可以參考下
    2020-05-05
  • node.js操作mongodb學習小結

    node.js操作mongodb學習小結

    這篇文章主要介紹了node.js操作mongodb學習小結,本文給出了mongodb創(chuàng)建數(shù)據(jù)庫、插入數(shù)據(jù)以及連接mongodb數(shù)據(jù)庫并查詢數(shù)據(jù)等代碼實例,需要的朋友可以參考下
    2015-04-04
  • node.js中的fs.utimes方法使用說明

    node.js中的fs.utimes方法使用說明

    這篇文章主要介紹了node.js中的fs.utimes方法使用說明,本文介紹了fs.utimes的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • Node.js如何優(yōu)雅的封裝一個實用函數(shù)的npm包的方法

    Node.js如何優(yōu)雅的封裝一個實用函數(shù)的npm包的方法

    這篇文章主要介紹了Node.js如何優(yōu)雅的封裝一個實用函數(shù)的npm包的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • 詳解離線安裝npm包的幾種方法

    詳解離線安裝npm包的幾種方法

    這篇文章主要介紹了詳解離線安裝npm包的幾種方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • Nodejs連接mysql并實現(xiàn)增、刪、改、查操作的方法詳解

    Nodejs連接mysql并實現(xiàn)增、刪、改、查操作的方法詳解

    這篇文章主要介紹了Nodejs連接mysql并實現(xiàn)增、刪、改、查操作的方法,結合實例形式詳細分析了nodejs針對mysql數(shù)據(jù)庫的的連接、mysql數(shù)據(jù)庫的創(chuàng)建及nodejs針對mysql增刪改查等相關操作具體實現(xiàn)技巧,需要的朋友可以參考下
    2018-01-01
  • nodejs部署到騰訊云的實現(xiàn)方法

    nodejs部署到騰訊云的實現(xiàn)方法

    本文主要介紹了nodejs部署到騰訊云的實現(xiàn)方法,文中根據(jù)實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • nodejs中使用throw進行異常處理的操作方法

    nodejs中使用throw進行異常處理的操作方法

    最近在寫一個nodejs項目時在思考一個問題: 在方法調(diào)其他方法的過程中,其他方法是采用return來返回特定格式的錯誤數(shù)據(jù)還是使用throw來直接拋出錯誤?所以本文給大家介紹了nodejs中使用throw進行異常處理的操作方法,需要的朋友可以參考下
    2024-12-12

最新評論

东丰县| 江门市| 嘉黎县| 阳春市| 荆门市| 白玉县| 章丘市| 龙川县| 山西省| 南靖县| 满城县| 江北区| 克山县| 滦南县| 宝丰县| 闸北区| 靖宇县| 舞阳县| 太湖县| 卢龙县| 广元市| 中江县| 沧源| 乐亭县| 边坝县| 和田市| 云阳县| 南郑县| 克东县| 那曲县| 邳州市| 南城县| 会同县| 冕宁县| 长岭县| 宁海县| 从化市| 海安县| 台安县| 犍为县| 柳林县|