为辛格尔顿课做装饰-打字稿 [英] Make decorator for singelton class -- typescript
问题描述
我正在使用带有Typescript的VueJS构建项目.使用服务而不是使用任何状态管理库(如Vuex),我感到很自在.但是,在编写服务时,我必须始终在每个服务类中复制粘贴一些代码,以使之成为:
I am building a project using VueJS with Typescript. I feel comfortable using services instead of any state management library like Vuex. But when writing services I have to always copy paste some code in each service class, to make it singelton as:
class MyService {
private static Instance: MyService;
public static getInstance() {
if (!MyService.Instance) {
MyService.Instance = new MyService();
}
return MyService.Instance;
}
private constructor() {}
}
我当时在考虑装饰器,所以我的问题是我们是否真的可以摆脱上面的代码并使用装饰器,我尝试了一些失败的尝试:
I was thinking about the decorators, so my question is can we really get rid of this above code and use decorator, I tried some failed attempts as:
function service<T>(): T {
const Instance: T | null = null;
return !Instance ? new T() : Instance;
}
@service<MyService>()
或
function service(constructor: Function) {
const Instance: MyService | null = null;
return !Instance ? new MyService() : Instance;
}
@service
,但是这些都行不通.我不确定装饰器是否会解决问题,其他方法也可以在这里工作,但是我没有任何想法,建议吗?
but these are not going to work. I am not sure that decorator will do the trick or not, other method may work here, but I don't have any idea, any suggestions?
推荐答案
也许您可以尝试以下操作
maybe you can try as follow
singletone.decorator.ts
singletone.decorator.ts
const serviceList: any[] = [];
export function AsSingletone() {
return (target: any): void => {
if(target.prototype.Instance) {
return;
}
serviceList.push(target);
Object.defineProperty(target, 'Instance', {
get: function () {
if (target.prototype.Instance) {
return target.prototype.Instance;
}
const instance = new target();
target.prototype.Instance = instance;
Object.defineProperty(target, 'Instance',
{ get: function () { return instance; } }
);
return instance;
}, configurable: true
});
};
}
export function registeredServiceList(): any[] {
return serviceList;
}
service.ts
service.ts
import { AsSingletone } from "./singletone.decorator";
@AsSingletone()
export class MyService {
public static readonly Instance: MyService;
}
获取访问权限
console.log(MyService.Instance);
设置抛出异常
MyService.Instance = (new MyService() as any).Instance as MyService;
VS代码片段模板,开始输入-singl
VS Code snippet template, start typing - singl
"Singletone": {
"prefix": ["singl"],
"body": [
"AsSingletone()\r",
"export class ${0}Service {\r",
"\tpublic static readonly Instance: ${0}Service;",
"}"],
"description": "Singletone service template"
}
这篇关于为辛格尔顿课做装饰-打字稿的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!