| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- import { Constructor } from "cc"
- type AbstractConstructor<T = any> = abstract new (...args: any[]) => T;
- // enum Priority{
- // DEFAULT,
- // }
- const Priority = {
- FRAMEWORK: 0,
- DEFAULT: 1,
- USER: 2
- }
- // 打包之后有问题不支持名称注入
- class SingletonAnnotation {
- private static TypeMap = new Map
- private static initNameMap = new Map<string, { target: any, consParam: [] }>()
- private static initTypeMap = new Map<Constructor | AbstractConstructor, { target: Constructor, consParam: [], priority: number }>()
- private static typeSet = new Set<any>
- /**
- *默认按类型注入, 如果填了类型或者名称,优先按填的name注入,只支持单例,不要填两个相同的name
- * @param name 名称注入|类型注入
- * @param priority 权重
- * @param consParam 构造函数的参数
- * @returns
- */
- static setSingleton(name?: string | Constructor | AbstractConstructor, priority: keyof (typeof Priority) = 'DEFAULT', ...consParam: any) {
- return function (target: any) {
- // 首字母小写注入
- let priority1 = Priority[priority]
- consParam = consParam || []
- let param = { target: target, consParam: consParam, priority: priority1 }
- if (!SingletonAnnotation.initTypeMap.has(target)) {
- SingletonAnnotation.initTypeMap.set(target, param);
- }
- // 使所有子类型的优先级最高
- if (name) {
- if (typeof name == "string") {
- SingletonAnnotation.initNameMap.set(name, param);
- if (SingletonAnnotation.initNameMap.has(name)) {
- throw new Error("重复注入")
- }
- } else {
- if (SingletonAnnotation.typeSet.has(name)) {
- let data = SingletonAnnotation.initTypeMap.get(name)
- if (data.priority == priority1) {
- throw new Error("重复注入")
- }
- if (data.priority > priority1) {
- return
- }
- }
- SingletonAnnotation.typeSet.add(name)
- SingletonAnnotation.initTypeMap.set(name, param);
- }
- }
- }
- }
- private static create(target: Constructor, consParam: any[]) {
- if (SingletonAnnotation.TypeMap.has(target)) {
- return SingletonAnnotation.TypeMap.get(target)
- }
- let instance = new target(...consParam);
- SingletonAnnotation.TypeMap.set(target, instance);
- return instance
- }
- /**
- * 默认按属性名称注入
- * @param name 名称构造器注入
- * @returns
- */
- static getSingleton(name?: Constructor | string | AbstractConstructor) {
- let res: PropertyDecorator = function (target, prop: string, desc?) {
- // 首字母小写注入
- let value: any
- // 是否初始化
- let init = false;
- return {
- get() {
- if (!init) {
- init = true
- if (!name) {
- name = prop
- }
- value = SingletonAnnotation.getValue(name)
- }
- return value
- },
- set(v) { init = true; value = v },
- }
- }
- return res
- }
- static getValue(name?: Constructor | string | AbstractConstructor) {
- if (!name) {
- return undefined;
- }
- let value
- if (typeof name != "string") {
- value = this.initObjByType(name);
- } else {
- value = this.initObjByName(name);
- }
- return value
- }
- private static initObjByName(name: string) {
- let v
- let param = SingletonAnnotation.initNameMap.get(name)
- if (param) {
- v = SingletonAnnotation.create(param.target, param.consParam)
- }
- return v
- }
- private static initObjByType(type: Constructor | AbstractConstructor) {
- // 首次创建类型需要重新对注入排序
- let param = SingletonAnnotation.initTypeMap.get(type)
- if (param) {
- let v = SingletonAnnotation.create(param.target, param.consParam)
- return v
- }
- return null
- }
- }
- // export {SingletonAnnotation.setSingleton as t,SingletonAnnotation.getSingleton}
- const setSingleton = SingletonAnnotation.setSingleton
- const getSingleton = SingletonAnnotation.getSingleton
- export {
- setSingleton,
- getSingleton
- }
|