ReactNative進階(三十一): IoC 框架 InversifyJS解讀

      網友投稿 720 2025-04-02

      文章目錄

      簡介

      為什么要有 InversifyJS?

      目標

      安裝

      應用示例

      步驟 1: 聲明接口和類型

      步驟 2: 使用 @injectable 和 @inject 裝飾器聲明依賴

      步驟 3: 創建和配置容器

      步驟 4: 解析依賴

      拓展閱讀

      簡介

      InversifyJS ,一個強大又輕量的控制反轉容器,提供給JavaScript 和 Node.js 應用使用,使用TypeScript編寫。

      InversifyJS 是一個輕量的 (4KB) 控制反轉容器 (IoC),可用于編寫 TypeScript 和 JavaScript 應用。 它使用類構造函數去定義和注入它的依賴。InversifyJS API 友好易懂, 鼓勵對 OOP 和 IoC 最佳實踐的應用.

      為什么要有 InversifyJS?

      JavaScript 現在支持面向對象編程,基于類的繼承。 這些特性不錯但事實上它們也是危險的。 我們需要一個優秀的面向對象設計(比如 SOLID),Composite Reuse等)來保護我們避免這些威脅。然而,面向對象的設計是復雜的,所以InversifyJS應運而生。

      InversifyJS 是一個工具,它能幫助 JavaScript 開發者,寫出出色的面向對象設計的代碼。

      目標

      InversifyJS有4個主要目標:

      允許JavaScript開發人員編寫遵循 SOLID 原則的代碼。

      促進并鼓勵遵守最佳的面向對象編程(OOP)和依賴注入(IoC)實踐。

      盡可能少的運行時開銷。

      提供藝術編程體驗和生態。

      安裝

      可以使用npm獲得最新的版本和類型定義:

      $ npm install inversify reflect-metadata --save

      1

      注:由于 InversifyJS 通過反射來獲取裝飾器的相關元數據,所以需要額外安裝庫

      reflect-metadata。

      Inversify npm 包已經包含了 InversifyJS 的類型定義

      :警示: 重要! InversifyJS 需要 TypeScript 的版本 >= 2.0 還有

      experimentalDecorators, emitDecoratorMetadata, types and lib 在 tsconfig.json 中 compilerOptions 的配置如下:

      { "compilerOptions": { "target": "es5", "lib": ["es6"], "types": ["reflect-metadata"], "module": "commonjs", "moduleResolution": "node", "experimentalDecorators": true, "emitDecoratorMetadata": true } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      inversifyjs需要現代JavaScript引擎,支持以下特性

      Reflect metadata

      Map

      Promise (Only required if using provider injection)

      Proxy (Only required if using activation handlers)

      如果運行環境不支持這些特性,可能需要導入 shim 或 polyfill.

      :警示: reflect-metadata polyfill 應該在您整個應用中只導入一次, 因為 Reflect 對象需要成為一個全局的單例。

      應用示例

      inversifyjs 基本用法和 API應用示例如下:

      步驟 1: 聲明接口和類型

      目標是編寫遵循依賴倒置原則的代碼。

      這意味著我們應該 ”依賴于抽象而不依賴于具體實現“ 。

      先聲明一些接口(抽象)。

      // file interfaces.ts interface Warrior { fight(): string; sneak(): string; } interface Weapon { hit(): string; } interface ThrowableWeapon { throw(): string; }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      Inversifyjs 需要在運行時使用類型標記作為標識符。接下來將使用 Symbol 作為標識符,也可以使用類或字符串。

      // file types.ts const TYPES = { Warrior: Symbol.for("Warrior"), Weapon: Symbol.for("Weapon"), ThrowableWeapon: Symbol.for("ThrowableWeapon") }; export { TYPES };

      1

      2

      3

      4

      5

      6

      7

      8

      9

      警示: 推薦使用 Symbol,但 InversifyJS 也支持使用類和字符串字面值。

      步驟 2: 使用 @injectable 和 @inject 裝飾器聲明依賴

      接下來,聲明一些類,實現剛剛聲明的接口。需要使用 @injectable 裝飾器去注解。

      當一個類依賴于某個接口時,我們需要使用 @inject 裝飾器,來定義在運行時可用的接口標識。在這種情況下,將使用 Symbol, 如 Symbol.for("Weapon") 和 Symbol.for("ThrowableWeapon") 作為運行時的標識。

      // file entities.ts import { injectable, inject } from "inversify"; import "reflect-metadata"; import { Weapon, ThrowableWeapon, Warrior } from "./interfaces" import { TYPES } from "./types"; @injectable() class Katana implements Weapon { public hit() { return "cut!"; } } @injectable() class Shuriken implements ThrowableWeapon { public throw() { return "hit!"; } } @injectable() class Ninja implements Warrior { private _katana: Weapon; private _shuriken: ThrowableWeapon; public constructor( @inject(TYPES.Weapon) katana: Weapon, @inject(TYPES.ThrowableWeapon) shuriken: ThrowableWeapon ) { this._katana = katana; this._shuriken = shuriken; } public fight() { return this._katana.hit(); } public sneak() { return this._shuriken.throw(); } } export { Ninja, Katana, Shuriken };

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      ReactNative進階(三十一): IoC 框架 InversifyJS解讀

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      如果更喜歡使用屬性注入而不是構造函數注入,那就可以不用聲明類的構造函數了,屬性注入方式如下:

      @injectable() class Ninja implements Warrior { @inject(TYPES.Weapon) private _katana: Weapon; @inject(TYPES.ThrowableWeapon) private _shuriken: ThrowableWeapon; public fight() { return this._katana.hit(); } public sneak() { return this._shuriken.throw(); } }

      1

      2

      3

      4

      5

      6

      7

      步驟 3: 創建和配置容器

      推薦在命名為 inversify.config.ts 的文件中創建和配置容器。這是唯一有耦合的地方。 在項目其余部分中的類,不應該包含對其他類的引用。

      // file inversify.config.ts import { Container } from "inversify"; import { TYPES } from "./types"; import { Warrior, Weapon, ThrowableWeapon } from "./interfaces"; import { Ninja, Katana, Shuriken } from "./entities"; const myContainer = new Container(); myContainer.bind(TYPES.Warrior).to(Ninja); myContainer.bind(TYPES.Weapon).to(Katana); myContainer.bind(TYPES.ThrowableWeapon).to(Shuriken); export { myContainer };

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      步驟 4: 解析依賴

      可以使用方法 get 從 Container 中獲得依賴。記得應該在項目根結構(盡可能靠近應用程序的入口點的位置)去解析依賴,避免服務器定位反模式。

      import { myContainer } from "./inversify.config"; import { TYPES } from "./types"; import { Warrior } from "./interfaces"; const ninja = myContainer.get(TYPES.Warrior); expect(ninja.fight()).eql("cut!"); // true expect(ninja.sneak()).eql("hit!"); // true

      1

      2

      3

      4

      5

      6

      7

      8

      正如我們所看到的,Katana and Shuriken 被成功的解析和注入進 Ninja。

      InversifyJS 支持 ES5 和 ES6 ,而且可以在沒有 TypeScript 環境下使用。

      不做知識的搬運工,只做知識的匯聚者!

      注:本文轉載于https://doc.inversify.cloud/zh_cn/,學習InversifyJS,看此文足矣??!墻裂推薦!!

      拓展閱讀

      InversifyJS【Github】

      中文文檔

      Java JavaScript

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:wps2019怎么給文章添加腳注? wps腳注的添加方法
      下一篇:如何有效嵌入5G技術優化生產制造效率,實現全連接智慧工廠?
      相關文章
      老司机亚洲精品影院在线观看| 亚洲午夜爱爱香蕉片| 亚洲av成人综合网| 在线观看亚洲成人| 亚洲AV无码乱码精品国产| 亚洲另类无码专区丝袜| 亚洲激情视频图片| 亚洲人xxx日本人18| 亚洲av无码一区二区三区天堂古代 | 日韩亚洲不卡在线视频中文字幕在线观看| 久久精品国产亚洲av麻豆小说 | 国产91成人精品亚洲精品| MM1313亚洲国产精品| 国产亚洲精品欧洲在线观看| 另类图片亚洲校园小说区| 午夜亚洲乱码伦小说区69堂| 亚洲av高清在线观看一区二区| 亚洲成av人片天堂网老年人| 亚洲国产成人久久综合一区77| 亚洲国产成人VA在线观看| 亚洲欧洲精品成人久久奇米网| 国产av无码专区亚洲国产精品| 亚洲日韩中文在线精品第一 | 中文字幕中韩乱码亚洲大片| 国产美女亚洲精品久久久综合| 亚洲尤码不卡AV麻豆| 亚洲av日韩av无码| 中文字幕亚洲色图| 亚洲人成网男女大片在线播放| 亚洲经典千人经典日产| 免费亚洲视频在线观看| 久久久精品国产亚洲成人满18免费网站 | 中文字幕人成人乱码亚洲电影 | 亚洲影院在线观看| 亚洲一区免费视频| 亚洲国产精品网站在线播放| avtt亚洲天堂| 国产亚洲AV无码AV男人的天堂| 亚洲AV日韩精品久久久久久久| 亚洲精品免费在线视频| 国产精品亚洲综合久久|