typescript nodejs 依賴注入的實現(xiàn)?相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
10年積累的成都網(wǎng)站設(shè)計、網(wǎng)站建設(shè)經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站設(shè)計后付款的網(wǎng)站建設(shè)流程,更有永寧免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
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í)行有先機(jī)是最高的,而這個依賴注入是支持手動注入一些實例對象,所有為了防止出現(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;
}上面代碼寫的稍微有一點(diǎn)點(diǎn)復(fù)雜,其他理解起來也不困難,大白話講就是 如果已經(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é)果:

看完上述內(nèi)容,你們掌握typescript nodejs 依賴注入的實現(xiàn)的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!
本文名稱:typescriptnodejs依賴注入的實現(xiàn)
分享地址:http://www.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è)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)