欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

import "reflect-metadata";
/**
 * 對象管理器
 */
const _partialContainer = new Map<string, any>();
const PARAMTYPES = "design:paramtypes";//需要反射的原數(shù)據(jù),有很多種選擇,我們這里選擇的是拿到構(gòu)造函數(shù)的參數(shù)類型,為了后續(xù)判斷
/**
 * 局部注入器,注入的是全局服務(wù),實例是全局共享
 */
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);//加入到對象管理器中,這個時候?qū)ο筮€沒有被創(chuàng)建
  }
}

   上面的代碼是創(chuàng)建一個類級別的裝飾器,表示凡是使用了這個裝飾器的類都會被依賴注入對象管理器管理,這里沒有馬上創(chuàng)建服務(wù),原因是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);// 反射拿到構(gòu)造函數(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è)置的共享數(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í)行結(jié)果:

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

總結(jié)

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

相關(guān)文章

  • Ubuntu中搭建Nodejs開發(fā)環(huán)境過程分享

    Ubuntu中搭建Nodejs開發(fā)環(huán)境過程分享

    這篇文章主要介紹了Ubuntu中搭建Nodejs開發(fā)環(huán)境過程,比較郁悶的是apt-get安裝失敗了,如果有遇到一樣問題的朋友,可以參考一下本文
    2014-06-06
  • Nodejs爬蟲進階教程之異步并發(fā)控制

    Nodejs爬蟲進階教程之異步并發(fā)控制

    這篇文章主要介紹了Nodejs爬蟲進階教程之異步并發(fā)控制的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • Nodejs異步回調(diào)之異常處理實例分析

    Nodejs異步回調(diào)之異常處理實例分析

    這篇文章主要介紹了Nodejs異步回調(diào)之異常處理,結(jié)合實例形式分析了nodejs基于中間件進行異步回調(diào)異常處理過程出現(xiàn)的問題與相應(yīng)的解決方法,需要的朋友可以參考下
    2018-06-06
  • pnpm的安裝及其使用教程(匯總)

    pnpm的安裝及其使用教程(匯總)

    pnpm是 Node.js 的替代包管理器,它是 npm 的直接替代品,速度更快、效率更高,它由 npm/yarn 衍生而來,但卻解決了 npm/yarn 內(nèi)部潛在的 bug,并且極大了地優(yōu)化了性能,本文給大家介紹pnpm的安裝及其使用,感興趣的朋友一起看看吧
    2023-12-12
  • Node.js JSON模塊用法實例分析

    Node.js JSON模塊用法實例分析

    這篇文章主要介紹了Node.js JSON模塊用法,結(jié)合實例形式分析了node.js json模塊的基本語法,以及使用json模塊進行json格式數(shù)據(jù)解析的相關(guān)操作技巧,需要的朋友可以參考下
    2019-01-01
  • 參考EventEmitter實現(xiàn)完整訂閱發(fā)布功能函數(shù)

    參考EventEmitter實現(xiàn)完整訂閱發(fā)布功能函數(shù)

    這篇文章主要為大家介紹了參考EventEmitter實現(xiàn)完整訂閱發(fā)布功能函數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • 解決node.js安裝包失敗的幾種方法

    解決node.js安裝包失敗的幾種方法

    nodejs安裝包失敗的原因可能有很多,下面這篇文章給大家整理三種方法來解決,大家可以試一試或許可以解決你的問題,下面來一起看一看。
    2016-09-09
  • Node.js使用SQLite數(shù)據(jù)庫方法大全

    Node.js使用SQLite數(shù)據(jù)庫方法大全

    Node.js是一種流行的JavaScript運行時,提供了許多有用的模塊和庫來構(gòu)建Web應(yīng)用程序,而SQLite是一種嵌入式關(guān)系型數(shù)據(jù)庫,它可以運行在各種操作系統(tǒng)上,包括Windows、Linux和Mac OS X等,在Node.js中,可以通過安裝sqlite3模塊來訪問SQLite數(shù)據(jù)庫
    2023-10-10
  • 學習 NodeJS 第八天:Socket 通訊實例

    學習 NodeJS 第八天:Socket 通訊實例

    本篇文章主要介紹了學習 NodeJS 第八天:Socket 通訊實例,非常具有實用價值,需要的朋友可以參考下。
    2016-12-12
  • node事件循環(huán)和process模塊實例分析

    node事件循環(huán)和process模塊實例分析

    這篇文章主要介紹了node事件循環(huán)和process模塊,結(jié)合實例形式分析了node事件循環(huán)和process模塊具體功能、使用方法及相關(guān)操作注意事項,需要的朋友可以參考下
    2020-02-02

最新評論