From 90acf352be638f99eb61f85af52cddbe8da309a8 Mon Sep 17 00:00:00 2001 From: gxkl Date: Mon, 28 Oct 2024 22:11:33 +0800 Subject: [PATCH 1/2] feat: add default inject init type qualifier --- core/core-decorator/src/decorator/Inject.ts | 64 ++++++++++++++++--- core/core-decorator/src/util/PrototypeUtil.ts | 4 ++ core/core-decorator/test/decorators.test.ts | 41 +++++++++++- .../fixtures/decators/ConstructorObject.ts | 27 ++++++-- .../decators/QualifierCacheService.ts | 28 +++++++- plugin/tegg/test/Inject.test.ts | 46 +++++++++++++ .../module-bar/BarConstructorService1.ts | 13 ++++ .../module-bar/BarConstructorService2.ts | 13 ++++ .../app/modules/module-bar/BarService1.ts | 12 ++++ .../app/modules/module-bar/BarService2.ts | 12 ++++ .../app/modules/module-bar/FooService.ts | 6 ++ .../app/modules/module-bar/package.json | 6 ++ .../app/modules/module-foo/FooService.ts | 6 ++ .../app/modules/module-foo/package.json | 6 ++ .../config/config.default.js | 20 ++++++ .../config/plugin.js | 13 ++++ .../package.json | 3 + 17 files changed, 304 insertions(+), 16 deletions(-) create mode 100644 plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarConstructorService1.ts create mode 100644 plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarConstructorService2.ts create mode 100644 plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarService1.ts create mode 100644 plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarService2.ts create mode 100644 plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/FooService.ts create mode 100644 plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/package.json create mode 100644 plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-foo/FooService.ts create mode 100644 plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-foo/package.json create mode 100644 plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/config/config.default.js create mode 100644 plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/config/plugin.js create mode 100644 plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/package.json diff --git a/core/core-decorator/src/decorator/Inject.ts b/core/core-decorator/src/decorator/Inject.ts index e9275299..49689659 100644 --- a/core/core-decorator/src/decorator/Inject.ts +++ b/core/core-decorator/src/decorator/Inject.ts @@ -1,20 +1,48 @@ -import { EggProtoImplClass, InjectObjectInfo, InjectConstructorInfo, InjectParams, InjectType } from '@eggjs/tegg-types'; +import { + EggProtoImplClass, + InjectObjectInfo, + InjectConstructorInfo, + InjectParams, + InjectType, + InitTypeQualifierAttribute, +} from '@eggjs/tegg-types'; import { PrototypeUtil } from '../util/PrototypeUtil'; import { ObjectUtils } from '@eggjs/tegg-common-util'; +import { QualifierUtil } from '../util/QualifierUtil'; + +function guessInjectInfo(clazz: EggProtoImplClass, name: PropertyKey, proto: any) { + let objName: PropertyKey | undefined; + let initType: string | undefined; + + if (typeof proto === 'function' && proto !== Object) { + // if property type is function and not Object( means maybe proto class ), then try to read EggPrototypeInfo.name as obj name + const info = PrototypeUtil.getProperty(proto as EggProtoImplClass); + objName = info?.name; + // try to read EggPrototypeInfo.initType as qualifier + if (info?.initType) { + const customInitType = QualifierUtil.getProperQualifier(clazz, name, InitTypeQualifierAttribute); + if (!customInitType) { + initType = info.initType; + } + } + } + + return { + objName, + initType, + }; +} export function Inject(param?: InjectParams | string) { const injectParam = typeof param === 'string' ? { name: param } : param; function propertyInject(target: any, propertyKey: PropertyKey) { let objName: PropertyKey | undefined; + let initType: string | undefined; if (!injectParam) { // try to read design:type from proto const proto = PrototypeUtil.getDesignType(target, propertyKey); - if (typeof proto === 'function' && proto !== Object) { - // if property type is function and not Object( means maybe proto class ), then try to read EggPrototypeInfo.name as obj name - const info = PrototypeUtil.getProperty(proto as EggProtoImplClass); - objName = info?.name; - } + ({ objName, initType } = guessInjectInfo(target.constructor, propertyKey, proto)); } else { // params allow string or object objName = injectParam?.name; @@ -31,16 +59,32 @@ export function Inject(param?: InjectParams | string) { PrototypeUtil.setInjectType(target.constructor, InjectType.PROPERTY); PrototypeUtil.addInjectObject(target.constructor as EggProtoImplClass, injectObject); + + if (initType) { + QualifierUtil.addProperQualifier(target.constructor, propertyKey, InitTypeQualifierAttribute, initType); + } } function constructorInject(target: any, parameterIndex: number) { const argNames = ObjectUtils.getConstructorArgNameList(target); const argName = argNames[parameterIndex]; + + let objName: PropertyKey | undefined; + let initType: string | undefined; + + if (!injectParam) { + // try to read proto from design:paramtypes + const protos = PrototypeUtil.getDesignParamtypes(target); + ({ objName, initType } = guessInjectInfo(target, argName, protos?.[parameterIndex])); + } else { + // params allow string or object + objName = injectParam?.name; + } + const injectObject: InjectConstructorInfo = { refIndex: parameterIndex, refName: argName, - // TODO get objName from design:type - objName: injectParam?.name || argName, + objName: objName || argName, }; if (injectParam?.optional) { @@ -49,6 +93,10 @@ export function Inject(param?: InjectParams | string) { PrototypeUtil.setInjectType(target, InjectType.CONSTRUCTOR); PrototypeUtil.addInjectConstructor(target as EggProtoImplClass, injectObject); + + if (initType) { + QualifierUtil.addProperQualifier(target, argName, InitTypeQualifierAttribute, initType); + } } return function(target: any, propertyKey?: PropertyKey, parameterIndex?: number) { diff --git a/core/core-decorator/src/util/PrototypeUtil.ts b/core/core-decorator/src/util/PrototypeUtil.ts index 70cd9f69..775b6ba2 100644 --- a/core/core-decorator/src/util/PrototypeUtil.ts +++ b/core/core-decorator/src/util/PrototypeUtil.ts @@ -284,4 +284,8 @@ export class PrototypeUtil { static getDesignType(clazz: EggProtoImplClass, propKey?: PropertyKey) { return MetadataUtil.getMetaData('design:type', clazz, propKey); } + + static getDesignParamtypes(clazz: EggProtoImplClass, propKey?: PropertyKey) { + return MetadataUtil.getMetaData('design:paramtypes', clazz, propKey); + } } diff --git a/core/core-decorator/test/decorators.test.ts b/core/core-decorator/test/decorators.test.ts index 670603a3..2250e5b4 100644 --- a/core/core-decorator/test/decorators.test.ts +++ b/core/core-decorator/test/decorators.test.ts @@ -16,7 +16,7 @@ import SingletonCache from './fixtures/decators/SingletonCache'; import { PrototypeUtil, QualifierUtil } from '..'; import QualifierCacheService from './fixtures/decators/QualifierCacheService'; import { FOO_ATTRIBUTE, FooLogger } from './fixtures/decators/FooLogger'; -import { ConstructorObject } from './fixtures/decators/ConstructorObject'; +import { ConstructorObject, ConstructorQualifierObject } from './fixtures/decators/ConstructorObject'; import { ChildDynamicMultiInstanceProto, ChildSingletonProto, @@ -90,8 +90,9 @@ describe('test/decorator.test.ts', () => { assert.deepStrictEqual(injectConstructors, [ { refIndex: 0, refName: 'xCache', objName: 'fooCache' }, { refIndex: 1, refName: 'cache', objName: 'cache' }, - { refIndex: 2, refName: 'optional1', objName: 'optional1', optional: true }, - { refIndex: 3, refName: 'optional2', objName: 'optional2', optional: true }, + { refIndex: 2, refName: 'otherCache', objName: 'cacheService' }, + { refIndex: 3, refName: 'optional1', objName: 'optional1', optional: true }, + { refIndex: 4, refName: 'optional2', objName: 'optional2', optional: true }, ]); }); }); @@ -107,6 +108,23 @@ describe('test/decorator.test.ts', () => { QualifierUtil.getProperQualifier(QualifierCacheService, property, InitTypeQualifierAttribute) === ObjectInitType.SINGLETON, ); }); + + it('should set default initType in inject', () => { + const properties = [ + { property: 'interfaceService', expected: undefined }, + { property: 'testContextService', expected: ObjectInitType.CONTEXT }, + { property: 'testSingletonService', expected: ObjectInitType.SINGLETON }, + { property: 'customNameService', expected: undefined }, + { property: 'customQualifierService1', expected: ObjectInitType.CONTEXT }, + { property: 'customQualifierService2', expected: ObjectInitType.CONTEXT }, + ]; + + for (const { property, expected } of properties) { + const qualifier = QualifierUtil.getProperQualifier(QualifierCacheService, property, InitTypeQualifierAttribute); + assert.strictEqual(qualifier, expected, `expect initType for ${property} to be ${expected}`); + } + }); + it('should work use Symbol.for', () => { assert(PrototypeUtil.isEggPrototype(QualifierCacheService)); const property = 'cache'; @@ -117,6 +135,7 @@ describe('test/decorator.test.ts', () => { QualifierUtil.getProperQualifier(QualifierCacheService, property, Symbol.for('Qualifier.InitType')) === ObjectInitType.SINGLETON, ); }); + it('constructor should work', () => { const constructorQualifiers = QualifierUtil.getProperQualifiers(ConstructorObject, 'xCache'); const constructorQualifiers2 = QualifierUtil.getProperQualifiers(ConstructorObject, 'cache'); @@ -126,6 +145,22 @@ describe('test/decorator.test.ts', () => { ]); assert.deepStrictEqual(constructorQualifiers2, []); }); + + it('should set default initType in constructor inject', () => { + const properties = [ + { property: 'xCache', expected: undefined }, + { property: 'cache', expected: ObjectInitType.SINGLETON }, + { property: 'ContextCache', expected: ObjectInitType.CONTEXT }, + { property: 'customNameCache', expected: undefined }, + { property: 'customQualifierCache1', expected: ObjectInitType.CONTEXT }, + { property: 'customQualifierCache2', expected: ObjectInitType.CONTEXT }, + ]; + + for (const { property, expected } of properties) { + const qualifier = QualifierUtil.getProperQualifier(ConstructorQualifierObject, property, InitTypeQualifierAttribute); + assert.strictEqual(qualifier, expected, `expect initType for ${property} to be ${expected}`); + } + }); }); describe('MultiInstanceProto', () => { diff --git a/core/core-decorator/test/fixtures/decators/ConstructorObject.ts b/core/core-decorator/test/fixtures/decators/ConstructorObject.ts index 2d48a559..4cd64567 100644 --- a/core/core-decorator/test/fixtures/decators/ConstructorObject.ts +++ b/core/core-decorator/test/fixtures/decators/ConstructorObject.ts @@ -1,9 +1,16 @@ +import { ObjectInitType } from '@eggjs/tegg-types'; import { SingletonProto } from '../../../src/decorator/SingletonProto'; -import { ICache } from './ICache'; import { Inject, InjectOptional } from '../../../src/decorator/Inject'; import { InitTypeQualifier } from '../../../src/decorator/InitTypeQualifier'; -import { ObjectInitType } from '@eggjs/tegg-types'; import { ModuleQualifier } from '../../../src/decorator/ModuleQualifier'; +import { ContextProto } from '../../../src/decorator/ContextProto'; +import { ICache } from './ICache'; + +@SingletonProto() +export class CacheService {} + +@ContextProto() +export class CacheContextService {} @SingletonProto() export class ConstructorObject { @@ -12,8 +19,20 @@ export class ConstructorObject { @ModuleQualifier('foo') @Inject({ name: 'fooCache'}) readonly xCache: ICache, @Inject() readonly cache: ICache, + @Inject() readonly otherCache: CacheService, @Inject({ optional: true }) readonly optional1?: ICache, @InjectOptional() readonly optional2?: ICache, - ) { - } + ) {} +} + +@SingletonProto() +export class ConstructorQualifierObject { + constructor( + @Inject() readonly xCache: ICache, + @Inject() readonly cache: CacheService, + @Inject() readonly ContextCache: CacheContextService, + @Inject('cacheService') readonly customNameCache: CacheService, + @InitTypeQualifier(ObjectInitType.CONTEXT) @Inject() readonly customQualifierCache1: CacheService, + @Inject() @InitTypeQualifier(ObjectInitType.CONTEXT) readonly customQualifierCache2: CacheService, + ) {} } diff --git a/core/core-decorator/test/fixtures/decators/QualifierCacheService.ts b/core/core-decorator/test/fixtures/decators/QualifierCacheService.ts index 94a1df38..9fa7a682 100644 --- a/core/core-decorator/test/fixtures/decators/QualifierCacheService.ts +++ b/core/core-decorator/test/fixtures/decators/QualifierCacheService.ts @@ -1,7 +1,13 @@ import { ObjectInitType } from '@eggjs/tegg-types'; -import { ContextProto, InitTypeQualifier, Inject, ModuleQualifier } from '../../..'; +import { ContextProto, InitTypeQualifier, Inject, ModuleQualifier, SingletonProto } from '../../..'; import { ICache } from './ICache'; +@ContextProto() +export class TestContextService {} + +@SingletonProto() +export class TestSingletonService {} + @ContextProto() export default class CacheService { @Inject({ @@ -10,4 +16,24 @@ export default class CacheService { @InitTypeQualifier(ObjectInitType.SINGLETON) @ModuleQualifier('foo') cache: ICache; + + @Inject() + interfaceService: ICache; + + @Inject() + testContextService: TestContextService; + + @Inject() + testSingletonService: TestSingletonService; + + @Inject('testSingletonService') + customNameService: TestSingletonService; + + @InitTypeQualifier(ObjectInitType.CONTEXT) + @Inject() + customQualifierService1: TestSingletonService; + + @Inject() + @InitTypeQualifier(ObjectInitType.CONTEXT) + customQualifierService2: TestSingletonService; } diff --git a/plugin/tegg/test/Inject.test.ts b/plugin/tegg/test/Inject.test.ts index f059bc6b..c0111505 100644 --- a/plugin/tegg/test/Inject.test.ts +++ b/plugin/tegg/test/Inject.test.ts @@ -3,6 +3,14 @@ import path from 'path'; import assert from 'assert'; import { BarService } from './fixtures/apps/optional-inject/app/modules/module-a/BarService'; import { FooService } from './fixtures/apps/optional-inject/app/modules/module-a/FooService'; +import { BarService1 } from './fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarService1'; +import { BarService2 } from './fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarService2'; +import { + BarConstructorService1, +} from './fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarConstructorService1'; +import { + BarConstructorService2, +} from './fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarConstructorService2'; describe('plugin/tegg/test/Inject.test.ts', () => { let app; @@ -47,6 +55,44 @@ describe('plugin/tegg/test/Inject.test.ts', () => { }); }); + describe('default initType qualifier', async () => { + beforeEach(async () => { + app = mm.app({ + baseDir: path.join(__dirname, 'fixtures/apps/same-name-singleton-and-context-proto'), + framework: require.resolve('egg'), + }); + await app.ready(); + }); + + it('should work with singletonProto', async () => { + await app.mockModuleContextScope(async () => { + const barService1: BarService1 = await app.getEggObject(BarService1); + assert.strictEqual(barService1.type(), 'singleton'); + }); + }); + + it('should work with contextProto', async () => { + await app.mockModuleContextScope(async () => { + const barService2: BarService2 = await app.getEggObject(BarService2); + assert.strictEqual(barService2.type(), 'context'); + }); + }); + + it('should work with singletonProto', async () => { + await app.mockModuleContextScope(async () => { + const barService1: BarConstructorService1 = await app.getEggObject(BarConstructorService1); + assert.strictEqual(barService1.type(), 'singleton'); + }); + }); + + it('should work with contextProto', async () => { + await app.mockModuleContextScope(async () => { + const barService2: BarConstructorService2 = await app.getEggObject(BarConstructorService2); + assert.strictEqual(barService2.type(), 'context'); + }); + }); + }); + it('should throw error if no proto found', async () => { app = mm.app({ baseDir: path.join(__dirname, 'fixtures/apps/invalid-inject'), diff --git a/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarConstructorService1.ts b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarConstructorService1.ts new file mode 100644 index 00000000..d43e37aa --- /dev/null +++ b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarConstructorService1.ts @@ -0,0 +1,13 @@ +import { Inject, SingletonProto } from '@eggjs/tegg'; +import { FooService } from '../module-foo/FooService'; + +@SingletonProto() +export class BarConstructorService1 { + constructor( + @Inject() readonly fooService: FooService, + ) {} + + type() { + return this.fooService.type; + } +} diff --git a/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarConstructorService2.ts b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarConstructorService2.ts new file mode 100644 index 00000000..05b3659f --- /dev/null +++ b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarConstructorService2.ts @@ -0,0 +1,13 @@ +import { Inject, SingletonProto } from '@eggjs/tegg'; +import { FooService } from './FooService'; + +@SingletonProto() +export class BarConstructorService2 { + constructor( + @Inject() readonly fooService: FooService, + ) {} + + type() { + return this.fooService.type; + } +} diff --git a/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarService1.ts b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarService1.ts new file mode 100644 index 00000000..4fff28eb --- /dev/null +++ b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarService1.ts @@ -0,0 +1,12 @@ +import { Inject, SingletonProto } from '@eggjs/tegg'; +import { FooService } from '../module-foo/FooService'; + +@SingletonProto() +export class BarService1 { + @Inject() + fooService: FooService; + + type() { + return this.fooService.type; + } +} diff --git a/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarService2.ts b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarService2.ts new file mode 100644 index 00000000..4fc04aeb --- /dev/null +++ b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/BarService2.ts @@ -0,0 +1,12 @@ +import { Inject, SingletonProto } from '@eggjs/tegg'; +import { FooService } from './FooService'; + +@SingletonProto() +export class BarService2 { + @Inject() + fooService: FooService; + + type() { + return this.fooService.type; + } +} diff --git a/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/FooService.ts b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/FooService.ts new file mode 100644 index 00000000..45b4b037 --- /dev/null +++ b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/FooService.ts @@ -0,0 +1,6 @@ +import { AccessLevel, ContextProto } from '@eggjs/tegg'; + +@ContextProto({ accessLevel: AccessLevel.PUBLIC }) +export class FooService { + type = 'context'; +} diff --git a/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/package.json b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/package.json new file mode 100644 index 00000000..0d34fd6f --- /dev/null +++ b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-bar/package.json @@ -0,0 +1,6 @@ +{ + "name": "module-a", + "eggModule": { + "name": "a" + } +} diff --git a/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-foo/FooService.ts b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-foo/FooService.ts new file mode 100644 index 00000000..472bce97 --- /dev/null +++ b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-foo/FooService.ts @@ -0,0 +1,6 @@ +import { AccessLevel, SingletonProto } from '@eggjs/tegg'; + +@SingletonProto({ accessLevel: AccessLevel.PUBLIC }) +export class FooService { + type = 'singleton'; +} diff --git a/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-foo/package.json b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-foo/package.json new file mode 100644 index 00000000..1c65fc26 --- /dev/null +++ b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/app/modules/module-foo/package.json @@ -0,0 +1,6 @@ +{ + "name": "module-foo", + "eggModule": { + "name": "foo" + } +} diff --git a/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/config/config.default.js b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/config/config.default.js new file mode 100644 index 00000000..6d1b8de5 --- /dev/null +++ b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/config/config.default.js @@ -0,0 +1,20 @@ +'use strict'; + +const path = require('path'); + +module.exports = function(appInfo) { + const config = { + keys: 'test key', + customLogger: { + xxLogger: { + file: path.join(appInfo.root, 'logs/xx.log'), + }, + }, + security: { + csrf: { + ignoreJSON: false, + } + }, + }; + return config; +}; diff --git a/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/config/plugin.js b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/config/plugin.js new file mode 100644 index 00000000..10d5c293 --- /dev/null +++ b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/config/plugin.js @@ -0,0 +1,13 @@ +'use strict'; + +exports.tracer = { + package: 'egg-tracer', + enable: true, +}; + +exports.teggConfig = { + package: '@eggjs/tegg-config', + enable: true, +}; + +exports.watcher = false; diff --git a/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/package.json b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/package.json new file mode 100644 index 00000000..978d31f2 --- /dev/null +++ b/plugin/tegg/test/fixtures/apps/same-name-singleton-and-context-proto/package.json @@ -0,0 +1,3 @@ +{ + "name": "egg-app" +} From e40634031d09a290061cf912a1cb625301ae82f2 Mon Sep 17 00:00:00 2001 From: gxkl Date: Tue, 29 Oct 2024 21:29:20 +0800 Subject: [PATCH 2/2] fix: add default qualifier --- .../src/factory/EggPrototypeCreatorFactory.ts | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/core/metadata/src/factory/EggPrototypeCreatorFactory.ts b/core/metadata/src/factory/EggPrototypeCreatorFactory.ts index fac8c21b..0ab54743 100644 --- a/core/metadata/src/factory/EggPrototypeCreatorFactory.ts +++ b/core/metadata/src/factory/EggPrototypeCreatorFactory.ts @@ -23,22 +23,23 @@ export class EggPrototypeCreatorFactory { static async createProto(clazz: EggProtoImplClass, loadUnit: LoadUnit): Promise { let properties: EggPrototypeInfo[] = []; + const defaultQualifier = [{ + attribute: InitTypeQualifierAttribute, + value: PrototypeUtil.getInitType(clazz, { + unitPath: loadUnit.unitPath, + moduleName: loadUnit.name, + })!, + }, { + attribute: LoadUnitNameQualifierAttribute, + value: loadUnit.name, + }]; + if (PrototypeUtil.isEggMultiInstancePrototype(clazz)) { const multiInstanceProtoInfo = PrototypeUtil.getMultiInstanceProperty(clazz, { unitPath: loadUnit.unitPath, moduleName: loadUnit.name, })!; for (const obj of multiInstanceProtoInfo.objects) { - const defaultQualifier = [{ - attribute: InitTypeQualifierAttribute, - value: PrototypeUtil.getInitType(clazz, { - unitPath: loadUnit.unitPath, - moduleName: loadUnit.name, - })!, - }, { - attribute: LoadUnitNameQualifierAttribute, - value: loadUnit.name, - }]; defaultQualifier.forEach(qualifier => { if (!obj.qualifiers.find(t => t.attribute === qualifier.attribute)) { obj.qualifiers.push(qualifier); @@ -56,7 +57,16 @@ export class EggPrototypeCreatorFactory { }); } } else { - properties = [ PrototypeUtil.getProperty(clazz)! ]; + const property = PrototypeUtil.getProperty(clazz)!; + if (!property.qualifiers) { + property.qualifiers = []; + } + defaultQualifier.forEach(qualifier => { + if (!property.qualifiers!.find(t => t.attribute === qualifier.attribute)) { + property.qualifiers!.push(qualifier); + } + }); + properties = [ property ]; } const protos: EggPrototype[] = []; for (const property of properties) {