如何使 tsyringe(dep 注入库)解析具有依赖性的 类?

How to make tsyringe (dep injection lib) resolve classes that have dependencies?

我显然误解了 TSyringe 应该如何解决具有依赖性的 classes。

我创建了一个最小的复制品。在我的 index.tsx 中,我按照文档中的说明进行操作并导入 reflect-metadata。如果我注入 singleton class 没有依赖关系,这个例子就有效:

// index.tsx
import "reflect-metadata";
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(<App />,  document.getElementById('root'));

单例class:

// _A.ts
import {inject, singleton} from 'tsyringe';

@singleton()
export class A {    
    get_msg() {
        return "Worked!";
    }
}

以及使用它的组件:

// App.tsx
import React from 'react';
import './App.css';
import {container} from "tsyringe";
import {A} from "./_A";

interface Props {
  a?: A
}

function App({a = container.resolve(A)}: Props) {
  return (
    <div className="App">
          {a.get_msg()}
    </div>
  );
}

export default App;

当我 运行 应用程序时,成功了!文本按预期打印。

但是,如果我创建第二个名为 B 的单例:

// _B.ts
import {singleton} from 'tsyringe';

@singleton()
export class B {
    get_msg() {
        return "Worked!";
    }
}

然后将B注入A得到消息:

// _A.ts
import {inject, singleton} from 'tsyringe';
import {B} from "./_B";

@singleton()
export class _A {
    constructor(private b: B) {
    }

    get_msg() {
        return this.b.get_msg();
    }
}

然后失败 Uncaught Error: TypeInfo not known for "A"

我有:

"experimentalDecorators": true,
"emitDecoratorMetadata": true,

在我的 tsconfig.ts 上,正如他们在 README 中指出的那样。

Syringe 不应该自动解析 B,将 B 注入 A,然后将 A 注入我的应用程序组件以便打印消息吗?

我错过了什么?

好的,我想通了。

为了保留打字稿元数据并让 reflect-metadata 发挥作用,我们需要将 babel-plugin-transform-typescript-metadata 添加到项目中。

但是,为了自定义 create-react-app,您需要 craco 库。那里有几个,但 craco 是我能支持 CRA 的唯一一个 4.x。 您不能使用最新的 (CRA 5.0),因为 none 这些库支持它。

所以:

1 - 安装 Craco 并进行设置。

2 - 安装 babel-plugin-transform-typescript-metadata 作为开发依赖项

3 - 将 craco.config.js 文件添加到您的项目以加载此插件:

module.exports = function ({ env: _env }) {
    return {
        babel: {
            plugins: [
                "babel-plugin-transform-typescript-metadata"
            ]
        },
    };
};

4 - 确保更新您的 package.json 以使用 craco 启动,以便进行配置覆盖:

  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "craco eject"
  },

就是这样,现在可以使用了。希望它能帮助那里的人。