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

本文介绍了如何在InversifyJS中处理多实例服务的管理,探讨了构造器注入、工厂注入和带参数实例化的工厂注入。通过依赖注入框架,可以避免代码耦合,提高代码可维护性,减少内存泄漏。文中详细阐述了各种注入方式的优缺点及适用场景,并强调了理解依赖注入设计理念的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

而在 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 时手动销毁这些实例。

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

工厂注入

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值