为辛格尔顿课做装饰-打字稿 [英] Make decorator for singelton class -- typescript

查看:34
本文介绍了为辛格尔顿课做装饰-打字稿的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆