使用依赖注入框架管理多实例服务(以 InversifyJS 为例)

以上就是我在使用依赖注入框架重构项目时,对于多实例服务管理的一些思考与实践。它成功地帮我完成了整个项目的重构,也让我对于依赖注入框架有了更深的理解。但于此同时,我也在实践中发现了许多依赖注入框架的局限性。但这并不说明依赖注入框架不够完善,而是说明了依赖注入作为一种设计模式与思想,它有其匹配的设计哲学。例如在上述的例子中,真正按照框架的最佳实践来说,我们应当只为服务注入行为抽象,而不是某些具体的变量数据,这对代码可测性来说非常重要。
摘要由CSDN通过智能技术生成

在大型项目的管理中,控制反转的思想是非常重要的。它可以帮助我们解耦代码,提高代码的可维护性。同时避免了不必要的重复实例化,降低内存泄漏的可能性。

而在 JS/TS 技术栈中,我们通常会使用依赖注入框架来帮助我们管理服务。这其中最佳的选择当然是 Angular 这种大而全的大型工程开发框架。而对于使用了其他 UI 框架的项目来说,我们同样可以额外引入一个轻量化的依赖注入框架。而 InversifyJS 就是其中的佼佼者。我们可以通过使用它,来见微知著地了解依赖注入的原理与设计哲学。

但最近在使用 Inversify 进行项目重构时,遇到了一个问题:众所周知依赖注入框架天生适合管理单例服务。它的设计哲学是 Everything as Service。但是在某些场景下,单例模式并不能解决一切问题,我们同样需要进行多实例的管理。那么我们该如何解决这个问题呢?

这并不是 Inversify 框架的问题,而其实是一个依赖注入框架下常见的设计疑惑,但是网上对此的解析资料却很少。

我看了很多使用了 InversifyJS 的项目,他们对此的方式就是直接在需要处实例化,不将其注册到容器中。这实际上是没有真正理解到依赖注入框架的内核。这样做的好处是简单,但是有很多弊端。由于我们无法在容器中统一管理这些实例,那么这些服务的生命周期将不受控制,在 dispose 时无法在容器中统一销毁这些实例。与不引入依赖注入框架一样,这样同样会带来内存泄漏的可能性。

那么该如何正确地处理这种情况呢?

构造器注入

一个最简便的改造方式是,我们将类的构造函数绑定到容器中。需要的时候从容器中获取类的构造器,再进行实例化。这样我们就可以在容器中统一管理这些实例了。

// 将 InstanceClass 的构造函数绑定到容器中
container
  .bind<interfaces.Newable<InstanceClass>>("Newable<InstanceClass>")
  .toConstructor<InstanceClass>(InstanceClass);
// 获取构造器
public constructor(
    @inject("Newable<InstanceClass>") InstanceClass: Newable<InstanceClass>,
) {
   
    this.instance1 = new InstanceClass();
    this.instance2 = new InstanceClass();
}

实例会跟随类的生命周期而存在,且该类能纳入容器中进行管理。但是这样做,实际上仍然无法在容器中统一管理这些实例的生命周期。如果我们需要在 dispose 时销毁这些实例,那么我们需要在类中手动实现 dispose 方法,并在 dispose 时手动销毁这些实例。

这样改造的好处是简单,但是很多时候并不是一个最优解,因为我们希望该实例本身能在注入框架的管理下,避免我们去手动的控制与销毁。

工厂注入

依赖注入框架天生不太好管理多实例的服务,但是如果利用工

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值