inversify依賴注入入門教程(保證你一學就會)

注意: 本篇文章時MobX和inversify的一個綜合,若是朋友沒有看過本人的MobX入門篇,請先看一下,這篇文章會用到上篇文章的環境。css

本人的MobX文章node

爲何要學習inversify呢?由於咱們在寫項目的時候要時刻考慮項目的穩定性,儘可能遵循設計原則,在這裏咱們要遵循依賴倒置原則,若是有不懂依賴倒置原則的朋友能夠點擊下方連接。react

依賴倒置原則webpack

inversify網站git

開發環境

根據MobX的開發環境咱們繼續配置.es6

  • 下載babel
npm install --save-dev @babel/preset-env
複製代碼
  • 配置.babelrc

大家能夠作一下對比,在這裏爲presets添加了一項@babel/preset-envgithub

{
    "plugins":[
        [
          "@babel/plugin-proposal-decorators",
          {
              "legacy":true
          }
        ],
        [
          "@babel/plugin-proposal-class-properties",
          {
              "loose":true
          }
          ]
          ],
    "presets":[
        "react-app",
        [
            "@babel/preset-env",
            {
              "useBuiltIns": "entry"
            }
          ]
        ]
    
}
複製代碼
  • 下載inversify所須要的包

除了下載inversify咱們還要下載reflect-metadataweb

npm install inversify reflect-metadata --save
複製代碼
  • 配置tsconfig.json

官方的配置npm

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

在這裏大家能夠和大家本身的tsconfig.json做對比,沒有的配置要添加json

下面是個人tsconfig.json,由於這是最終的tsconfig.json文件,你先配置道這裏後面有的配置尚未配。

{
  "compilerOptions": {
    "baseUrl": ".",
    "outDir": "build/dist",
    "module": "commonjs",
    "target": "es5",
    "lib": ["es6", "dom"],
    "types": ["reflect-metadata", "jest", "node"],
    "sourceMap": true,
    "allowJs": true,
    "jsx": "react",
    "moduleResolution": "node",
    "rootDir": "src",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "importHelpers": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "exclude": [
    "node_modules",
    "build",
    "scripts",
    "acceptance-tests",
    "webpack",
    "jest",
    "src/setupTests.ts"
  ]
}
複製代碼

inversify的配置就完了,可是你如今要是運行的話會報錯,由於App.test.tsx文件裏的it報錯了,沒有測試框架。

  • 下載jest測試框架
npm install --save-dev jest
複製代碼
  • 配置package.json文件

把"scripts"裏的"test"改成jest官網的配置,也就是

"scripts": {
    "start": "react-scripts-ts start",
    "build": "react-scripts-ts build",
    "test": "jest",
    "eject": "react-scripts-ts eject"
  },
複製代碼
  • 配置tsconfig.json

給"compilerOptions"裏面的"type"數組裏在添加一項"jest"

"types": ["reflect-metadata", "jest"],
複製代碼

jest配置完畢,你覺得到這裏就結束了嗎?不!你怕是想的有點多! 還有,你一運行仍是會報錯,它說讓你在tsconfig.json裏的types裏面在加上"node"

"types": ["reflect-metadata", "jest", "node"],
複製代碼

這下也就對應了我上面tsconfig.json的總配置。

環境配置完畢

inversify入門

文件目錄

文件目錄

在這裏官網給的例子建立了4個文件,接口一個文件,type類型一個文件, inversify.config.ts文件, 實現接口的類一個文件。在這裏我把接口和實現類放在了一個文件中。

  • index.tsx

在這裏要引入import "reflect-metadata",沒有則報錯。

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import "reflect-metadata" // 引入文件
import App from './App';
import './index.css';
import registerServiceWorker from './registerServiceWorker';


ReactDOM.render(<App />,document.getElementById('root') as HTMLElement);
registerServiceWorker();
複製代碼
  • TYPE.ts
const TYPE = {
    IStor: Symbol.for("IStor")
}
export default TYPE
複製代碼
  • store.ts
import { injectable } from "inversify";
import { action, computed, observable } from "mobx"

export interface IStor {
    num: number;
    map: Map<string,object>;
    list: string[];
    obj: object;
    retunum:string;
    addNum:number;
    add:()=>void;

}

@injectable()
class Store implements IStor {

    @observable public num: number = 0;
    @observable public map: Map<string,object> = new Map();
    @observable public list: string[] = ["a","b"];
    @observable public obj: object = {name:"Mobx"};

    @computed
    public get retunum() {
        return `${this.num}~~~~~~~~`
    }
    @computed
    public get addNum() {
        return this.num + 10;
    }


    @action.bound
    public add() {
        this.num++;
    }
    

}
export default Store 
複製代碼
  • inversify.config.ts
import { Container, ContainerModule } from "inversify";
// import { Container } from "inversify";
import Store, { IStor } from "./store"
import TYPE from "./TYPE"

const myContainer = new Container({defaultScope: "Singleton"})

const myStore = new ContainerModule(bind=>{
    // 把接口和實現類對應起來
    bind<IStor>(TYPE.IStor).to(Store)
})

const initilize = ():void => {
    // 初始化,將myStore和myContainer聯繫起來
    myContainer.load(myStore)
}
initilize();
// 常規寫法
// const myContainer = new Container();
// myContainer.bind<IStor>(TYPE.IStor).to(Store);

export { myContainer, myStore }
複製代碼
  • Casual.tsx

在這裏我把兩個代碼都寫出來了,大家能夠對比一下。

import { observer } from 'mobx-react';
import * as React from "react"
// import Store from '../store/store';
import { myContainer } from "../store/inversify.config"
import { IStor } from "../store/store"
import TYPE from "../store/TYPE"




@observer
class Casual extends React.Component<{},{}> {
    // 將獲得store的對象,
    private store: IStor = myContainer.get<IStor>(TYPE.IStor)



   public render() {
        return (
            <div>
                <h1>{this.store.num}</h1>
                <h2>{this.store.retunum}</h2>
                <h2>{this.store.addNum}</h2>
                <button onClick={this.onClickAdd}>增長num</button>
            </div>
        )
    }

    public onClickAdd=()=>{
        this.store.add()
    };


}




// interface IProps {
//     store?: Store;
//   }

// @inject("store")
// @observer
// class Casual extends React.Component<IProps,{}> {

//     constructor(props:IProps) {
//         super(props)
//     }


//    public render() {
//         return (
//             <div>
//                 <h1>{this.props.store!.num}</h1>
//                 <h2>{this.props.store!.retunum}</h2>
//                 <h2>{this.props.store!.addNum}</h2>
//                 <button onClick={this.onClickAdd}>增長num</button>
//             </div>
//         )
//     }

//     public onClickAdd=()=>{
//         this.props.store!.add()
//     };


// }
export default Casual
複製代碼
  • App.tsx

再也不使用mobx-react的@inject()的引入方式,不在使用Provider

// import { Provider } from "mobx-react"
import * as React from 'react';
import './App.css';
import Casual from "./component/Casual"
// import Store  from './store/store';

// const store = {
//   store: new Store()
// }

class App extends React.Component {
  
  // public render() {
  //   return (
  //     <Provider {...store}>
  //     <div>
  //       <Casual  />
  //     </div>
  //     </Provider>
  //   );
  // }
  public render() {
    return (
      <div>
        <Casual  />
      </div>
    );
  }
}

export default App;
複製代碼

在這裏咱們的代碼書寫完畢。

任何人,未經本人贊成,不得轉載本篇文章。

相關文章
相關標籤/搜索