1

我在实现单例时遇到了麻烦,因为标记为@singleton() 的类在每个resolve() 上都被重新创建。

这是示例

// Foo.ts This is singleton and and must be created only once
import { injectable, singleton } from "tsyringe";

@injectable()
@singleton()
export class Foo {
  constructor() {
    console.log("Constractor of Foo");
  }
}
// Bar.ts this is Bar and should be created every time. It uses the singleton
import { inject, injectable, Lifecycle, scoped } from "tsyringe";
import { Foo } from "./Foo";

@injectable()
export class Bar {
  constructor(@inject("Foo") private foo: Foo) {
    console.log("Constractor of Bar");
  }
}
// main.ts this is resolving Bar two times.
// expected output:
// Constractor of Foo
// Constractor of Bar
// Constractor of Bar

// Actual output:
// Constractor of Foo
// Constractor of Bar
// Constractor of Foo
// Constractor of Bar

import "reflect-metadata";
import { container } from "tsyringe";
import { Bar } from "./Bar";
import { Foo } from "./Foo";

container.register("Foo", { useClass: Foo });
container.register("Bar", { useClass: Bar });

const instance = container.resolve(Bar);
const instance1 = container.resolve(Bar);

如何获得所需的行为?

4

2 回答 2

2

我认为你让你的生活变得更加困难。我发现您所做的事情和您提出的解决方案存在一些问题。这是装饰器的源代码@singleton()

function singleton<T>(): (target: constructor<T>) => void {
  return function(target: constructor<T>): void {
    injectable()(target);
    globalContainer.registerSingleton(target);
  };
}
  • 首先,你不需要用 装饰,@injectable()因为 tsyringe 已经添加了@singleton().
  • 最后,如果您只是不注册FooBar它们将在函数中自动注册为单例({ lifecycle: Lifecycle.Singleton }当然,已设置选项)globalContainer.registerSingleton(target)
于 2021-05-04T14:30:19.763 回答
1

单例应按如下方式注册

container.register(
  "Foo",
  { useClass: Foo },
  { lifecycle: Lifecycle.Singleton } // <- this is important
);
于 2021-03-31T08:19:44.187 回答