Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix merge qualifier #250

Merged
merged 2 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions core/aop-runtime/src/PointCutGraphHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ function findPointCutAdvice(globalGraph: GlobalGraph, protoNode: GraphNode<Proto
const injectProto = globalGraph.findDependencyProtoNode(protoNode.val.proto, {
objName: property.name,
refName: property.name,
qualifiers: [
...property?.qualifiers ?? [],
...QualifierUtil.getProtoQualifiers(clazz),
],
qualifiers: QualifierUtil.mergeQualifiers(
property?.qualifiers ?? [],
QualifierUtil.getProtoQualifiers(clazz),
),
});
if (injectProto) {
result.add(injectProto);
Expand Down
17 changes: 17 additions & 0 deletions core/core-decorator/src/util/QualifierUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,21 @@ export class QualifierUtil {
if (clazzQualifiers.length !== requestQualifiers.length) return false;
return QualifierUtil.matchQualifiers(clazzQualifiers, requestQualifiers);
}

static mergeQualifiers(...qualifiers: QualifierInfo[][]): QualifierInfo[] {
const result: QualifierInfo[] = [];
const temp: Record<QualifierAttribute, QualifierValue> = {};
for (const qualifierList of qualifiers) {
for (const { attribute, value } of qualifierList) {
temp[attribute] = value;
}
}
for (const key of Reflect.ownKeys(temp)) {
result.push({
attribute: key,
value: temp[key],
});
}
return result;
}
}
8 changes: 4 additions & 4 deletions core/dynamic-inject-runtime/src/EggObjectFactoryPrototype.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ export class EggObjectFactoryPrototype implements EggPrototype {

constructor(clazz: EggProtoImplClass<EggObjectFactory>, loadUnit: LoadUnit, prototypeInfo: EggPrototypeInfo) {
this.clazz = clazz;
this.qualifiers = [
...QualifierUtil.getProtoQualifiers(clazz),
...(prototypeInfo.qualifiers ?? []),
];
this.qualifiers = QualifierUtil.mergeQualifiers(
QualifierUtil.getProtoQualifiers(clazz),
(prototypeInfo.qualifiers ?? []),
);
this.id = IdenticalUtil.createProtoId(loadUnit.id, NameUtil.getClassName(this.clazz));
this.initType = prototypeInfo.initType;
this.accessLevel = prototypeInfo.accessLevel;
Expand Down
40 changes: 20 additions & 20 deletions core/metadata/src/impl/EggPrototypeBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ export class EggPrototypeBuilder {
builder.injectType = PrototypeUtil.getInjectType(clazz);
builder.injectObjects = PrototypeUtil.getInjectObjects(clazz) || [];
builder.loadUnit = loadUnit;
builder.qualifiers = [
...QualifierUtil.getProtoQualifiers(clazz),
...(ctx.prototypeInfo.qualifiers ?? []),
];
builder.qualifiers = QualifierUtil.mergeQualifiers(
QualifierUtil.getProtoQualifiers(clazz),
(ctx.prototypeInfo.qualifiers ?? []),
);
builder.properQualifiers = ctx.prototypeInfo.properQualifiers ?? {};
builder.multiInstanceConstructorIndex = PrototypeUtil.getMultiInstanceConstructorIndex(clazz);
builder.multiInstanceConstructorAttributes = PrototypeUtil.getMultiInstanceConstructorAttributes(clazz);
Expand All @@ -66,36 +66,36 @@ export class EggPrototypeBuilder {
private tryFindDefaultPrototype(injectObject: InjectObject): EggPrototype {
const propertyQualifiers = QualifierUtil.getProperQualifiers(this.clazz, injectObject.refName);
const multiInstancePropertyQualifiers = this.properQualifiers[injectObject.refName as string] ?? [];
return EggPrototypeFactory.instance.getPrototype(injectObject.objName, this.loadUnit, [
...propertyQualifiers,
...multiInstancePropertyQualifiers,
]);
return EggPrototypeFactory.instance.getPrototype(injectObject.objName, this.loadUnit, QualifierUtil.mergeQualifiers(
propertyQualifiers,
multiInstancePropertyQualifiers,
));
}

private tryFindContextPrototype(injectObject: InjectObject): EggPrototype {
const propertyQualifiers = QualifierUtil.getProperQualifiers(this.clazz, injectObject.refName);
const multiInstancePropertyQualifiers = this.properQualifiers[injectObject.refName as string] ?? [];
return EggPrototypeFactory.instance.getPrototype(injectObject.objName, this.loadUnit, [
...propertyQualifiers,
...multiInstancePropertyQualifiers,
{
return EggPrototypeFactory.instance.getPrototype(injectObject.objName, this.loadUnit, QualifierUtil.mergeQualifiers(
propertyQualifiers,
multiInstancePropertyQualifiers,
[{
attribute: InitTypeQualifierAttribute,
value: ObjectInitType.CONTEXT,
},
]);
}],
));
}

private tryFindSelfInitTypePrototype(injectObject: InjectObject): EggPrototype {
const propertyQualifiers = QualifierUtil.getProperQualifiers(this.clazz, injectObject.refName);
const multiInstancePropertyQualifiers = this.properQualifiers[injectObject.refName as string] ?? [];
return EggPrototypeFactory.instance.getPrototype(injectObject.objName, this.loadUnit, [
...propertyQualifiers,
...multiInstancePropertyQualifiers,
{
return EggPrototypeFactory.instance.getPrototype(injectObject.objName, this.loadUnit, QualifierUtil.mergeQualifiers(
propertyQualifiers,
multiInstancePropertyQualifiers,
[{
attribute: InitTypeQualifierAttribute,
value: this.initType,
},
]);
}],
));
}

private findInjectObjectPrototype(injectObject: InjectObject): EggPrototype {
Expand Down
16 changes: 8 additions & 8 deletions core/metadata/src/model/ProtoDescriptorHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,21 +96,21 @@ export class ProtoDescriptorHelper {
const res: ProtoDescriptor[] = [];

for (const obj of instanceProperty.objects) {
let qualifiers = [
...QualifierUtil.getProtoQualifiers(clazz),
...obj.qualifiers,
];
let qualifiers = QualifierUtil.mergeQualifiers(
QualifierUtil.getProtoQualifiers(clazz),
obj.qualifiers,
);
qualifiers = ProtoDescriptorHelper.addDefaultQualifier(qualifiers, instanceProperty.initType, options.instanceModuleName);
const injectObjects: InjectObjectDescriptor[] = PrototypeUtil.getInjectObjects(clazz)
.map(t => {
const qualifiers = QualifierUtil.getProperQualifiers(clazz, t.refName);
const instanceQualifier = obj.properQualifiers?.[t.refName] ?? [];
return {
...t,
qualifiers: [
...qualifiers,
...instanceQualifier,
],
qualifiers: QualifierUtil.mergeQualifiers(
qualifiers,
instanceQualifier,
),
};
});
res.push(new ClassProtoDescriptor({
Expand Down
19 changes: 10 additions & 9 deletions core/metadata/src/model/graph/GlobalGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { FrameworkErrorFormater } from 'egg-errors';
import { EggPrototypeNotFound, MultiPrototypeFound } from '../../errors';
import { GlobalModuleNodeBuilder } from './GlobalModuleNodeBuilder';
import { ModuleDescriptor } from '../ModuleDescriptor';
import { QualifierUtil } from '@eggjs/core-decorator';

export interface GlobalGraphOptions {
// TODO next major version refactor to force strict
Expand Down Expand Up @@ -145,10 +146,10 @@ export class GlobalGraph {
for (const node of this.protoGraph.nodes.values()) {
if (node.val.selectProto({
name: injectObject.objName,
qualifiers: [
...injectObject.qualifiers,
...qualifiers,
],
qualifiers: QualifierUtil.mergeQualifiers(
injectObject.qualifiers,
qualifiers,
),
moduleName: proto.instanceModuleName,
})) {
result.push(node);
Expand Down Expand Up @@ -189,13 +190,13 @@ export class GlobalGraph {
if (!loadUnitQualifier) {
return this.findDependencyProtoNode(proto, {
...injectObject,
qualifiers: [
...injectObject.qualifiers,
{
qualifiers: QualifierUtil.mergeQualifiers(
injectObject.qualifiers,
[{
attribute: LoadUnitNameQualifierAttribute,
value: proto.instanceModuleName,
},
],
}],
),
});
}
throw FrameworkErrorFormater.formatError(new MultiPrototypeFound(injectObject.objName, injectObject.qualifiers));
Expand Down
6 changes: 5 additions & 1 deletion core/runtime/src/impl/EggObjectUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ export class EggObjectUtil {
return target[p];
}
const obj = getObj();
return obj[p];
const val = obj[p];
if (typeof val === 'function') {
return val.bind(obj);
}
return val;
},
getOwnPropertyDescriptor(_target: {}, p: string | symbol): PropertyDescriptor | undefined {
const obj = getObj();
Expand Down
5 changes: 3 additions & 2 deletions plugin/dal/lib/TransactionalAOP.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Advice, AdviceContext, IAdvice } from '@eggjs/tegg/aop';
import { AccessLevel, EggProtoImplClass, ObjectInitType } from '@eggjs/tegg';
import { PropagationType } from '@eggjs/tegg/transaction';
import assert from 'node:assert';
import { MysqlDataSource } from '@eggjs/dal-runtime';

export interface TransactionalParams {
Expand All @@ -17,7 +16,9 @@ export class TransactionalAOP implements IAdvice<EggProtoImplClass, Transactiona
public async around(ctx: AdviceContext<EggProtoImplClass, TransactionalParams>, next: () => Promise<any>): Promise<void> {
const { propagation, dataSourceGetter } = ctx.adviceParams!;
const dataSource = dataSourceGetter();
assert(propagation === PropagationType.REQUIRED, '事务注解目前只支持 REQUIRED 机制');
if (propagation === PropagationType.ALWAYS_NEW) {
return await dataSource.beginTransactionScope(next);
}
return await dataSource.beginTransactionScope(next);
}
}
8 changes: 4 additions & 4 deletions plugin/tegg/lib/EggCompatibleProtoImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ export class EggCompatibleProtoImpl implements EggPrototype {
const name = ctx.prototypeInfo.name;
const id = IdenticalUtil.createProtoId(loadUnit.id, name);
const proto = new EggCompatibleProtoImpl(
id, name, clazz, ctx.prototypeInfo.initType, loadUnit.id, [
...QualifierUtil.getProtoQualifiers(clazz),
...(ctx.prototypeInfo.qualifiers ?? []),
],
id, name, clazz, ctx.prototypeInfo.initType, loadUnit.id, QualifierUtil.mergeQualifiers(
QualifierUtil.getProtoQualifiers(clazz),
(ctx.prototypeInfo.qualifiers ?? []),
),
);
return proto;
}
Expand Down
6 changes: 6 additions & 0 deletions plugin/tegg/test/ConstructorModuleConfig.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import mm from 'egg-mock';
import assert from 'assert';
import path from 'path';
import { Foo } from './fixtures/apps/constructor-module-config/modules/module-with-config/foo';

describe('plugin/tegg/test/ModuleConfig.test.ts', () => {
let app;
Expand Down Expand Up @@ -37,4 +38,9 @@ describe('plugin/tegg/test/ModuleConfig.test.ts', () => {
});
});
});

it('construct proxy should work', async () => {
const foo: Foo = await app.getEggObject(Foo);
foo.log();
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
import { EggLogger } from 'egg-logger';

@SingletonProto({
accessLevel: AccessLevel.PUBLIC,
Expand All @@ -7,8 +8,15 @@ export class Foo {
readonly foo: string;
readonly bar: string;

constructor(@Inject() moduleConfig: Record<string, any>) {
constructor(
@Inject() moduleConfig: Record<string, any>,
@Inject() readonly logger: EggLogger,
) {
this.foo = moduleConfig.features.dynamic.foo;
this.bar = moduleConfig.features.dynamic.bar;
}

log() {
this.logger.info('foo');
}
}
Loading