typescript nodejs 依賴注入的實(shí)現(xiàn)?相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
10年積累的成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有永寧免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
import "reflect-metadata"; /** * 對(duì)象管理器 */ const _partialContainer = new Map<string, any>(); const PARAMTYPES = "design:paramtypes";//需要反射的原數(shù)據(jù),有很多種選擇,我們這里選擇的是拿到構(gòu)造函數(shù)的參數(shù)類型,為了后續(xù)判斷 /** * 局部注入器,注入的是全局服務(wù),實(shí)例是全局共享 */ 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);//加入到對(duì)象管理器中,這個(gè)時(shí)候?qū)ο筮€沒有被創(chuàng)建 } }
上面的代碼是創(chuàng)建一個(gè)類級(jí)別的裝飾器,表示凡是使用了這個(gè)裝飾器的類都會(huì)被依賴注入對(duì)象管理器管理,這里沒有馬上創(chuàng)建服務(wù),原因是reflect-metadata
的執(zhí)行有先機(jī)是最高的,而這個(gè)依賴注入是支持手動(dòng)注入一些實(shí)例對(duì)象,所有為了防止出現(xiàn)注入?yún)?shù)為undefined所以創(chuàng)建實(shí)例的工作是放在后面的,請(qǐng)看接下來的代碼:
/** * * @param type 已創(chuàng)建的實(shí)例對(duì)象 */ export function addServiceInGlobal(...types: Array<Object>) { for (const iterator of types) { _partialContainer.set(iterator.constructor.name, iterator); } }
上面的方法是手動(dòng)注入實(shí)例對(duì)象時(shí)調(diào)用的,我們需要提高這個(gè)方法的執(zhí)行優(yōu)先級(jí),具體的實(shí)例會(huì)在后面演示,接下來是最重要部分,創(chuàng)建實(shí)例部分:
export function serviceProvider<T>(service: ServiceType<T>): T { if (_partialContainer.has(service.name) && !_partialContainer.get(service.name).name) return _partialContainer.get(service.name);// 如果實(shí)例已經(jīng)被創(chuàng)建就直接返回 const params: Array<any> = Reflect.getMetadata(PARAMTYPES, service);// 反射拿到構(gòu)造函數(shù)的參數(shù)類型 const constrparams = params.map(item => { // 實(shí)例化參數(shù)中的依賴 if (!_partialContainer.has(item.name)) throw new Error(`${item}沒有被注入`);// 如果沒有注入就拋出異常 if (item.length)// 表示這個(gè)類型還有其它依賴 return serviceProvider(item);// 遞歸繼續(xù)獲取其他依賴 if (_partialContainer.has(item.name) && !_partialContainer.get(item.name).name) return _partialContainer.get(item.name);// 如果實(shí)例已經(jīng)被創(chuàng)建就直接返回 const obj = new item();// 已經(jīng)沒有其他依賴了 開始創(chuàng)建實(shí)例 _partialContainer.set(item.name, obj);// 替換對(duì)象管理器中原來沒有實(shí)例化的對(duì)象 return obj; }); const obj = new service(...constrparams); // 這里表示對(duì)象沒有被創(chuàng)建,開始創(chuàng)建對(duì)象 _partialContainer.set(service.name, obj);// 替換對(duì)象管理器中原來沒有實(shí)例化的對(duì)象 return obj; }
上面代碼寫的稍微有一點(diǎn)點(diǎn)復(fù)雜,其他理解起來也不困難,大白話講就是 如果已經(jīng)實(shí)例化了直接返回實(shí)例不然就開始對(duì)象以及創(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("我在測(cè)試注入"); } } @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); // 添加手動(dòng)創(chuàng)建的實(shí)例對(duì)象到對(duì)象管理器 const service = serviceProvider(Init); // 開始創(chuàng)建實(shí)例 service.start()// 執(zhí)行
上面的實(shí)例中得到一下執(zhí)行結(jié)果:
看完上述內(nèi)容,你們掌握typescript nodejs 依賴注入的實(shí)現(xiàn)的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!
本文名稱:typescriptnodejs依賴注入的實(shí)現(xiàn)
分享地址:http://chinadenli.net/article28/gshpcp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、網(wǎng)站策劃、做網(wǎng)站、網(wǎng)站排名、外貿(mào)建站、網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)