如何在 Tsyringe 中实现单例
How to implement singleton in Tsyringe
我在实现单例时遇到问题,因为标记为 @singleton() 的 class 在每次 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);
如何获得所需的行为?
单例注册如下
container.register(
"Foo",
{ useClass: Foo },
{ lifecycle: Lifecycle.Singleton } // <- this is important
);
我认为你让你的生活更加困难。我发现您所做的事情和您提出的解决方案有一些问题。这是 @singleton()
装饰器的 source code:
function singleton<T>(): (target: constructor<T>) => void {
return function(target: constructor<T>): void {
injectable()(target);
globalContainer.registerSingleton(target);
};
}
- 首先,你不需要用
@injectable()
装饰,因为tsyringe已经用@singleton()
. 添加了它
- 最后,如果你不注册
Foo
和 Bar
它们将自动注册为单例(当然 { lifecycle: Lifecycle.Singleton }
选项已经设置)在 globalContainer.registerSingleton(target)
函数。
我在实现单例时遇到问题,因为标记为 @singleton() 的 class 在每次 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);
如何获得所需的行为?
单例注册如下
container.register(
"Foo",
{ useClass: Foo },
{ lifecycle: Lifecycle.Singleton } // <- this is important
);
我认为你让你的生活更加困难。我发现您所做的事情和您提出的解决方案有一些问题。这是 @singleton()
装饰器的 source code:
function singleton<T>(): (target: constructor<T>) => void {
return function(target: constructor<T>): void {
injectable()(target);
globalContainer.registerSingleton(target);
};
}
- 首先,你不需要用
@injectable()
装饰,因为tsyringe已经用@singleton()
. 添加了它
- 最后,如果你不注册
Foo
和Bar
它们将自动注册为单例(当然{ lifecycle: Lifecycle.Singleton }
选项已经设置)在globalContainer.registerSingleton(target)
函数。