91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

VSCode中依賴注入的原理是什么

發布時間:2023-02-08 09:14:53 來源:億速云 閱讀:108 作者:iii 欄目:軟件技術

這篇文章主要介紹“VSCode中依賴注入的原理是什么”,在日常操作中,相信很多人在VSCode中依賴注入的原理是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”VSCode中依賴注入的原理是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

依賴注入做了什么

假設以下情況:

  • 服務模塊 A,依賴服務 B;

  • 服務模塊 B;

  • 功能模塊 Feature,依賴服務 A 和 B;

按照普通的寫法就是:

class B {}

class A {
    constructor() {
        // 在 A 的構造器中 new B
        this.b = new B();
    }
}

class Feature {
    constructor() {
        this.a = new A();
        this.b = new B();
    }
}

// 使用時
const feature = new Feature();

代碼簡單明了,存在一些問題,比如:如果 A 和 Feature 依賴的 B 需要是同一個實例,以上的寫法將會初始化兩個 B 實例。【推薦學習:vscode教程、編程教學】

簡單修改一下:

class A {
    constructor(b: B) {
        this.b = b;
    }
}

class Feature {
    constructor(a, b) {
        this.a = a;
        this.b = b;
    }
}

// 使用時
const b = new B();
const a = new A(b);
const feature = new Feature(a, b);

某個模塊初始化時,先在外部將其所依賴的模塊創建出來,通過參數的形式傳入功能模塊。這樣的寫法就是「依賴注入」。

現在這種寫法的問題在于:手動傳參的形式,必須人工保證 new 的順序,即必須獲得 a, b 實例才能執行 new Feature。

當依賴關系變得復雜時,創建一個功能模塊之前很有可能需要無數個基礎模塊,這時候復雜度將會非常高。

想象一種模式:存在一個模塊控制器,或者說「服務管理器」來管理這些依賴關系:

class Feature {
    // 聲明這個模塊依賴 idA, idB
    idA
    idB
}

// 告知「服務管理器」,怎么找對應的模塊
services[idA] = A;
services[idB] = B;

// 使用時
const feature = services.createInstance(Feature);

這個 services 承載的不就是之前的「手工」過程嗎?
在 createInstance(Feature) 時,分析 Feature 所依賴的模塊:

  • 如果所依賴的模塊還未創建出實例,遞歸創建出該服務實例,最終返回;

  • 如果所依賴的模塊已有實例,返回該實例;

  • 找齊后通過參數注入 Feature,完成初始化;
    VSCode 實現的正是這么一套「依賴注入體系」。

依賴注入怎么做?

要實現這樣一套功能,大致需要:

  • 一個類如何聲明其依賴的服務 id,即給定一個 類,外部如何知道他依賴了哪些服務?

  • 如何管理管理服務?

  • 如何創建某個模塊?

下文會實現一個最簡單的模型,涵蓋主體流程。

添加依賴信息

如何給一個 類 打上烙印,聲明它所依賴的服務呢?
將問題再次抽象:如何給一個類加上額外的信息?
其實,每個類在 es5 下都是 Function,而每個 Function 說到底也只是 Object ,只要給 Object 加上幾個字段來標識所需要的服務 id,就可以完成所需要的功能。
通過 「參數裝飾器」的寫法,可以很容易做到這一點:

// 參數裝飾器 
const decorator = (
    target: Object, // 被裝飾的目標,這里為 Feature
    propertyName: string, 
    index: number // 參數的位置索引
) => {
    target['deps'] = [{        index,        id: 'idA',    }];
}
class Feature {
    name = 'feature';
    a: any;
    constructor(
        // 參數裝飾器
        @decorator a: any,
    ) {
        this.a = a;
    }
}
console.log('Feature.deps', Feature['deps']);
// [{ id: 'idA', index: 0 }]

通過這種方式,通過 Feature (之后會稱之為 構造器 ctor)就可以獲取到 serviceId。

服務管理

使用 Map 來進行管理,一個 id 對應一個 服務 ctor。

class A {
    name = 'a';
}

// 服務集
class ServiceCollection {
    // 服務集合
    // key 為服務標識
    // value 為 服務ctor
    private entries = new Map<string, any>();

    set(id: string, ctor: any) {
        this.entries.set(id, ctor);   
    }

    get(id: string): any {
        return this.entries.get(id);
    }
}

const services = new ServiceCollection();

// 聲明服務 A id 為 idA
services.set('idA', A);

現在,就可以通過 Feature 來找到所依賴的服務的構造器了

// 通過 Feature 找到所依賴的 A
const serviceId = Feature['deps'][0].id; // idA
console.log(
    'Feature.deps', 
    services.get(serviceId) // A
);

模塊創建

具體思路為:

  • 如果所依賴的模塊還未創建出實例,遞歸創建出該服務實例,最終返回;

  • 如果所依賴的模塊已有實例,返回該實例;

  • 找齊后通過參數注入 Feature,完成初始化;

這里先上一個簡單的 demo,只有一層的依賴(即所依賴的服務沒有依賴其他服務),簡單的講,就是沒有遞歸能力:

class InstantiationService {
    services: ServiceCollection;

    constructor(services: ServiceCollection) {
        this.services = services;
    }

    createInstance(ctor: any) {
        // 1. 獲取 ctor 依賴的 服務id
        // 結果為: ['idA']
        const depIds = ctor['deps'].map((item: any) => item.id);

        // 2. 獲取服務 id 對應的 服務構造器
        // 結果為:[A]
        const depCtors = depIds.map((id: string) => services.get(id));

        // 3. 獲取服務實例
        // 結果為: [ A { name: 'a'} ]
        const args = depCtors.map((ctor: any) => new ctor());

        // 4. 依賴的服務作為參數注入,實例化所需要模塊
        // 結果為:[ Feature { name: 'feature', a }]
        const result = new ctor(...args);

        return result;
    }
}

const instantiation = new InstantiationService(services);

// 使用時
const feature = instantiation.createInstance(Feature);

要使用 Feature 時,只需要調用 createInstance,不用管他所依賴的服務是否被初始化,instantiation 幫我們做了這個事情。

到此,關于“VSCode中依賴注入的原理是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新龙县| 澄迈县| 天水市| 盐城市| 湘潭市| 广东省| 桐城市| 遵化市| 万荣县| 阜新市| 腾冲县| 吉水县| 长宁县| 富阳市| 博白县| 逊克县| 曲靖市| 饶河县| 江安县| 迁西县| 平谷区| 叙永县| 峨眉山市| 休宁县| 大埔县| 洛扎县| 台湾省| 津南区| 游戏| 治多县| 墨脱县| 和硕县| 玛沁县| 寻甸| 江达县| 左贡县| 大足县| 资兴市| 武乡县| 怀化市| 东乡|