【翻譯】InversifyJS 中文文檔

和網友 Jeff-Tian 一塊兒翻譯了 InversifyJS 英文文檔, ღ( ´・ᴗ・` )比心html

倉庫地址:github.com/NeoYo/inver… 歡迎 fork or startnode

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

InversifyJS 地址:github.com/inversify/I…es6

InversifyJS官網:inversify.iogithub

InversifyJS中文文檔:www.inversify.cnnpm

簡介

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

爲何要有 InversifyJS?

JavaScript 如今支持面向對象編程,基於類的繼承。 這些特性不錯但事實上它們也是 危險的。 咱們須要一個優秀的面向對象設計(好比 SOLIDComposite Reuse等)來保護咱們避免這些威脅。然而,面向對象的設計是複雜的,因此咱們建立了 InversifyJS。json

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

目標

InversifyJS有4個主要目標:markdown

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

  2. 促進並鼓勵遵照最佳的面向對象編程和依賴注入實踐。

  3. 儘量少的運行時開銷。

  4. 提供藝術編程體驗和生態

業內評價

Nate Kohari - Ninject的做者

"Nice work! I've taken a couple shots at creating DI frameworks for JavaScript and TypeScript, but the lack of RTTI really hinders things.The ES7 metadata gets us part of the way there (as you've discovered). Keep up the great work!"

Michel Weststrate - MobX的做者

Dependency injection like InversifyJS works nicely

使用 InversifyJS 的公司

image.png

安裝

您能夠使用npm得到最新的版本和類型定義:

$ npm install inversify reflect-metadata --save
複製代碼

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

:警示: 重要! InversifyJS 須要 TypeScript 的版本 >= 2.0 還有 experimentalDecorators, emitDecoratorMetadata, types and libtsconfig.json 中 compilerOptions 的配置以下:

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

inversifyjs須要現代JavaScript引擎,支持如下特性

若是您的運行環境不支持這些特性,您可能須要導入 shimpolyfill

:警示: reflect-metadata polyfill 應該在您整個應用中只導入一次 由於 Reflect 對象須要成爲一個全局的單例。 更多細節能夠在這裏找到。

查看維基中的開發環境 polyfills , 還能夠從基本示例中去學習.

基礎部分

讓咱們一塊兒看下 inversifyjs 的基本用法和 API:

步驟 1: 聲明接口和類型

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

這意味着咱們應該 」依賴於抽象而不依賴於具體實現「 。

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

// file interfaces.ts

interface Warrior {
    fight(): string;
    sneak(): string;
}

interface Weapon {
    hit(): string;
}

interface ThrowableWeapon {
    throw(): string;
}
複製代碼

Inversifyjs 須要在運行時使用類型標記做爲標識符。接下來將使用 Symbol 做爲標識符,您也可使用類或字符串。

// file types.ts

const TYPES = {
    Warrior: Symbol.for("Warrior"),
    Weapon: Symbol.for("Weapon"),
    ThrowableWeapon: Symbol.for("ThrowableWeapon")
};

export { TYPES };

複製代碼

警示: 推薦使用 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 };
複製代碼

若是您更喜歡使用屬性注入而不是構造函數注入,那就能夠不用聲明類的構造函數了:

@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(); }
}
複製代碼

步驟 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<Warrior>(TYPES.Warrior).to(Ninja);
myContainer.bind<Weapon>(TYPES.Weapon).to(Katana);
myContainer.bind<ThrowableWeapon>(TYPES.ThrowableWeapon).to(Shuriken);

export { myContainer };
複製代碼

步驟 4: 解析依賴

您可使用方法 get<T>Container 中得到依賴。記得您應該在根結構(儘量靠近應用程序的入口點的位置)去解析依賴,避免服務器定位反模式

import { myContainer } from "./inversify.config";
import { TYPES } from "./types";
import { Warrior } from "./interfaces";

const ninja = myContainer.get<Warrior>(TYPES.Warrior);

expect(ninja.fight()).eql("cut!"); // true
expect(ninja.sneak()).eql("hit!"); // true
複製代碼

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

InversifyJS 支持 ES5 和 ES6 並且能夠在沒有 TypeScript 環境下使用。 前往 JavaScript 示例瞭解更多

InversifyJS 特性 和 API

讓咱們一塊兒看看 InversifyJS 的特性!

請查閱 wiki 獲取更多細節。

請查閱 wiki 獲取更多細節。

生態

爲了提供藝術般的開發體驗,咱們也不斷努力:

請查閱 生態 wiki 頁 去了解更多。

Support

若是您遇到任何問題,咱們樂意幫忙。您可使用 問題頁 報告問題。

若是您想要和開發團隊分享您的想法或者加入咱們,您能夠參加 論壇討論。您也能夠查看 wiki 來了解更多關於 InversifyJS。

Acknowledgements

Thanks a lot to all the contributors, all the developers out there using InversifyJS and all those that help us to spread the word by sharing content about InversifyJS online. Without your feedback and support this project would not be possible.

License

License under the MIT License (MIT)

Copyright © 2015-2017 Remo H. Jansen

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

相關文章
相關標籤/搜索