清除 inversify-js 容器并解析新的服务实例

Clear inversify-js container and resolve new service instances

我有一个react-native application frontend using inversify-js

我已经构建了一些服务 类 以使用 IOC(使用反向容器),这些服务旨在作为一个单独实例与其他服务共享。他们有一个 init/destroy 方法来帮助清除服务的内部状态。

init/destroy 机制工作正常,但最重要的是,如果有一种方法可以“清除”反转容器单例,从头开始重建我所有的单例服务,那就太好了。

示例:

src/services/A.ts

@injectable()
export class A extends Service {
  constructor() {
    super();
  }

  init() {
    super.init();

    // [...] Initialize A's state
  }

  destroy() {
    // [...] Destroy A's state

    super.destroy();
  }

  method() {
    // [...] Provide functionality to other services (maintaining A's state)
  }
}

src/services/B.ts

@injectable()
export class B extends Service {
  constructor(
    b: B // receive injected instance of service A using constructor injection (inversify)
  ) {
    super();
  }

  init() {
    super.init();

    // [...] Initialize B's state
  }

  destroy() {
    // [...] Destroy B's state

    super.destroy();
  }

  method() {
    // [...] Provide functionality to other services (maintaining B's state, using also service A)
    this.a.method();
  }
}

src/inversify/container.ts

export const containerModule = new ContainerModule((bind) => {
  // Services
  bind<A>(A).toSelf().inSingletonScope();
  bind<B>(B).toSelf().inSingletonScope();
});

const container = new Container();

container.load(containerModule);

export default container;

index.ts

let a = container.get<A>(A);
let b = container.get<A>(B);

// [...] use services

// Destroy services (es: logout/reload app)
a.destroy();
b.destroy();

// Here I'd also like to "reset" the container
// container.reset(); // like this?

// [...] After some time (maybe login again?)

// I'd like these two to be new singleton instances (!== from previous a,b)
a = container.get<A>(A);
b = container.get<A>(B);

我应该能够从容器 (container.unload(containerModule)) 中“卸载”ContainerModule 并再次“加载”它?虽然看起来很老套,但我一直在寻找类似的解决方案。

我调查了这个问题,但最终还是不需要相同的“重置”功能:

我在另一个答案中建议的解决方案是简单地放弃当前 container 并创建一个新实例,非常干净且易于理解。

但是后来我查看了源代码,发现已经包含了这样的功能。

container.unbindAll()是!

这个API无条件地将容器重置为新鲜状态(几乎是新鲜的,稍后解释)而不需要创建一个新的实例。 Link to source code.

我之前说“几乎新鲜”,这是因为容器还有一个鲜为人知(至少对我而言)的特性,叫做 snapshots。事实证明,您甚至可以将绑定设置的多个快照存储在一个容器中。

有意思。因此,如果您在注册任何绑定之前为一个空容器制作快照,并在稍后恢复它,则它是有效的“重置”。

最后,container.unload(containerModule) 完全正确,一点也不hacky。可以称之为选择性重置

如果你阅读源代码你会发现,在所有这些方法的背后,都是关于修改内部 _bindingDictionary。那是存储所有绑定的地方。