何时使用 container.get 与构造函数 @inject?
When to use container.get vs constructor @inject?
我是使用 InversifyJS 的新手,我看到很多 class 的基本示例以及使用 @inject 作为依赖项的构造函数。像这样...
export class Service {
protected depA: DependencyA;
protected depB: DependencyB;
constructor(
@inject(DependencyA) dependencyA: DependencyA,
@inject(DependencyB) dependencyB: DependencyB
) {
this.depA = dependencyA;
this.depB = dependencyB;
}
}
那些注入的依赖项有 0 个进一步的依赖项。
但是,我有一些同事不使用它,而是使用类似...
private readonly service = container.get<Interface>(TYPES.InterfaceSymbol);
调用任何必要的依赖服务。
对于这种示例案例,我想更好地了解何时使用一个而不是另一个。将其写为嵌套列表,其中进一步缩进的列表项是其依赖项。
- 根服务
- 业务逻辑服务
- 回购服务
- GeneralDbConnectionService
- 业务逻辑B服务
- 回购服务
- GeneralDbConnectionService
加上一个替代 console.log() 的 LoggerService,应该可以注入到任何服务中。
在这种情况下,我什么时候应该使用带@inject params 的构造函数而不是container.get()(或者其他一些你知道我不知道的方式)?
对于大多数用例,您应该依赖使用 @inject
的自动依赖注入,而不是使用 container.get
手动查询容器。任何依赖注入框架的要点是,您只需编写 类 及其依赖项,让框架为您处理所有连接,而无需编写样板代码。您不需要手动查询容器,除非您处于框架无法确定依赖关系图的特殊情况。
补充一下 Martin 的回答,DI 也与生命周期有关。 Rest API 中的某些 classes 自然是请求范围的,而其他 classes 是自然的单例,例如中间件 classes。
如果单例 class 想要为当前 HTTP 请求获取一个实例,通常使用 container.get
。不过,只要有可能,更喜欢普通的构造函数注入。
示例API
如果它能为您提供解决方案的想法,这里有一些代码片段来自我的 Node.js API,专注于非功能性行为:
DI 组合
当 API 启动时,它会注册依赖项,这里有一些技巧。对于每种类型,您都应该考虑生命周期。一般来说,单例意味着请求 A 可能会干扰请求 B 的风险更大。
一些对象,例如 ClaimsPrincipal
或 LogEntry
自然是请求范围的。
DI 分辨率
我的 API 使用 Inversify Express Utils,它为每个请求创建一个子容器,这也是一种常见的模式,例如 .NET 使用它。
用于管理横切关注点的 class 使用 container.get
,尽管这是例外而不是规则:
所有其他 类
DI 管道的要点是处理管道,然后启用简单代码。所以大多数 classes 看起来像这样,很容易推理,也很好测试:
我是使用 InversifyJS 的新手,我看到很多 class 的基本示例以及使用 @inject 作为依赖项的构造函数。像这样...
export class Service {
protected depA: DependencyA;
protected depB: DependencyB;
constructor(
@inject(DependencyA) dependencyA: DependencyA,
@inject(DependencyB) dependencyB: DependencyB
) {
this.depA = dependencyA;
this.depB = dependencyB;
}
}
那些注入的依赖项有 0 个进一步的依赖项。
但是,我有一些同事不使用它,而是使用类似...
private readonly service = container.get<Interface>(TYPES.InterfaceSymbol);
调用任何必要的依赖服务。
对于这种示例案例,我想更好地了解何时使用一个而不是另一个。将其写为嵌套列表,其中进一步缩进的列表项是其依赖项。
- 根服务
- 业务逻辑服务
- 回购服务
- GeneralDbConnectionService
- 回购服务
- 业务逻辑B服务
- 回购服务
- GeneralDbConnectionService
- 回购服务
- 业务逻辑服务
加上一个替代 console.log() 的 LoggerService,应该可以注入到任何服务中。
在这种情况下,我什么时候应该使用带@inject params 的构造函数而不是container.get()(或者其他一些你知道我不知道的方式)?
对于大多数用例,您应该依赖使用 @inject
的自动依赖注入,而不是使用 container.get
手动查询容器。任何依赖注入框架的要点是,您只需编写 类 及其依赖项,让框架为您处理所有连接,而无需编写样板代码。您不需要手动查询容器,除非您处于框架无法确定依赖关系图的特殊情况。
补充一下 Martin 的回答,DI 也与生命周期有关。 Rest API 中的某些 classes 自然是请求范围的,而其他 classes 是自然的单例,例如中间件 classes。
如果单例 class 想要为当前 HTTP 请求获取一个实例,通常使用 container.get
。不过,只要有可能,更喜欢普通的构造函数注入。
示例API
如果它能为您提供解决方案的想法,这里有一些代码片段来自我的 Node.js API,专注于非功能性行为:
DI 组合
当 API 启动时,它会注册依赖项,这里有一些技巧。对于每种类型,您都应该考虑生命周期。一般来说,单例意味着请求 A 可能会干扰请求 B 的风险更大。
一些对象,例如 ClaimsPrincipal
或 LogEntry
自然是请求范围的。
DI 分辨率
我的 API 使用 Inversify Express Utils,它为每个请求创建一个子容器,这也是一种常见的模式,例如 .NET 使用它。
用于管理横切关注点的 class 使用 container.get
,尽管这是例外而不是规则:
所有其他 类
DI 管道的要点是处理管道,然后启用简单代码。所以大多数 classes 看起来像这样,很容易推理,也很好测试: