如何使 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"
},
就是这样,现在可以使用了。希望它能帮助那里的人。
我显然误解了 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"
},
就是这样,现在可以使用了。希望它能帮助那里的人。