Merge pull request #15504 from hajekjiri/bug/fix-undefined-injection

fix(core): fix race condition in class dependency resolution from imported modules
This commit is contained in:
Kamil Mysliwiec
2025-08-07 08:54:48 +02:00
committed by GitHub
5 changed files with 113 additions and 146 deletions

View File

@@ -49,21 +49,42 @@ class TransientProvider {}
@Injectable()
class RequestProvider {}
@Injectable()
class ForeignTransientProvider {}
@Injectable()
export class Dependant {
constructor(
private readonly transientProvider: TransientProvider,
private readonly foreignTransientProvider: ForeignTransientProvider,
@Inject(RequestProvider)
private readonly requestProvider: RequestProvider,
) {}
public checkDependencies() {
expect(this.transientProvider).to.be.instanceOf(TransientProvider);
expect(this.foreignTransientProvider).to.be.instanceOf(
ForeignTransientProvider,
);
expect(this.requestProvider).to.be.instanceOf(RequestProvider);
}
}
@Global()
@Module({
providers: [
{
provide: ForeignTransientProvider,
scope: Scope.TRANSIENT,
useClass: ForeignTransientProvider,
},
],
exports: [ForeignTransientProvider],
})
export class ModuleWithForeignTransientProvider {}
@Global()
@Module({
providers: [
@@ -98,6 +119,12 @@ export class GlobalModuleWithRequestProvider {}
@Module({
imports: [
/*
* ForeginTransientProvider will be resolved quickly because its host module is imported first.
* IMPORTANT: Do not move this module, otherwise we may not catch future regressions.
*/
ModuleWithForeignTransientProvider,
GlobalModule1,
GlobalModule2,
GlobalModule3,
@@ -115,7 +142,7 @@ export class GlobalModuleWithRequestProvider {}
export class AppModule {}
describe('Many global modules', () => {
it('should inject request-scoped useFactory provider and transient-scoped useClass provider from different modules', async () => {
it('should inject request-scoped and transient-scoped providers from different modules', async () => {
const moduleBuilder = Test.createTestingModule({
imports: [AppModule],
});

View File

@@ -2263,6 +2263,22 @@
},
"id": "-1303681274"
},
"-831049991": {
"source": "594986539",
"target": "-1721730431",
"metadata": {
"type": "class-to-class",
"sourceModuleName": "InputModule",
"sourceClassName": "InputService",
"targetClassName": "CircularService",
"sourceClassToken": "InputService",
"targetClassToken": "CircularService",
"targetModuleName": "CircularModule",
"keyOrIndex": 0,
"injectionType": "constructor"
},
"id": "-831049991"
},
"-886102564": {
"source": "208171089",
"target": "671882984",
@@ -2280,6 +2296,22 @@
},
"id": "-886102564"
},
"-2146943494": {
"source": "-234035039",
"target": "928565345",
"metadata": {
"type": "class-to-class",
"sourceModuleName": "RequestChainModule",
"sourceClassName": "RequestChainService",
"targetClassName": "HelperService",
"sourceClassToken": "RequestChainService",
"targetClassToken": "HelperService",
"targetModuleName": "HelperModule",
"keyOrIndex": 0,
"injectionType": "constructor"
},
"id": "-2146943494"
},
"-2003045613": {
"source": "-377928898",
"target": "-616397055",
@@ -2312,38 +2344,6 @@
},
"id": "-881420795"
},
"-831049991": {
"source": "594986539",
"target": "-1721730431",
"metadata": {
"type": "class-to-class",
"sourceModuleName": "InputModule",
"sourceClassName": "InputService",
"targetClassName": "CircularService",
"sourceClassToken": "InputService",
"targetClassToken": "CircularService",
"targetModuleName": "CircularModule",
"keyOrIndex": 0,
"injectionType": "constructor"
},
"id": "-831049991"
},
"-2146943494": {
"source": "-234035039",
"target": "928565345",
"metadata": {
"type": "class-to-class",
"sourceModuleName": "RequestChainModule",
"sourceClassName": "RequestChainService",
"targetClassName": "HelperService",
"sourceClassToken": "RequestChainService",
"targetClassToken": "HelperService",
"targetModuleName": "HelperModule",
"keyOrIndex": 0,
"injectionType": "constructor"
},
"id": "-2146943494"
},
"-1816180282": {
"source": "-848516688",
"target": "-1673986099",

View File

@@ -2181,22 +2181,6 @@
},
"id": "1976848738"
},
"-2105726668": {
"source": "-1803759743",
"target": "1010833816",
"metadata": {
"type": "class-to-class",
"sourceModuleName": "PropertiesModule",
"sourceClassName": "PropertiesService",
"targetClassName": "token",
"sourceClassToken": "PropertiesService",
"targetClassToken": "token",
"targetModuleName": "PropertiesModule",
"keyOrIndex": "token",
"injectionType": "property"
},
"id": "-2105726668"
},
"-21463590": {
"source": "-1378706112",
"target": "1004276345",
@@ -2213,6 +2197,22 @@
},
"id": "-21463590"
},
"-2105726668": {
"source": "-1803759743",
"target": "1010833816",
"metadata": {
"type": "class-to-class",
"sourceModuleName": "PropertiesModule",
"sourceClassName": "PropertiesService",
"targetClassName": "token",
"sourceClassToken": "PropertiesService",
"targetClassToken": "token",
"targetModuleName": "PropertiesModule",
"keyOrIndex": "token",
"injectionType": "property"
},
"id": "-2105726668"
},
"-1657371464": {
"source": "-1673986099",
"target": "1919157847",
@@ -2247,6 +2247,22 @@
},
"id": "-1303681274"
},
"-831049991": {
"source": "594986539",
"target": "-1721730431",
"metadata": {
"type": "class-to-class",
"sourceModuleName": "InputModule",
"sourceClassName": "InputService",
"targetClassName": "CircularService",
"sourceClassToken": "InputService",
"targetClassToken": "CircularService",
"targetModuleName": "CircularModule",
"keyOrIndex": 0,
"injectionType": "constructor"
},
"id": "-831049991"
},
"-886102564": {
"source": "208171089",
"target": "671882984",
@@ -2264,6 +2280,22 @@
},
"id": "-886102564"
},
"-2146943494": {
"source": "-234035039",
"target": "928565345",
"metadata": {
"type": "class-to-class",
"sourceModuleName": "RequestChainModule",
"sourceClassName": "RequestChainService",
"targetClassName": "HelperService",
"sourceClassToken": "RequestChainService",
"targetClassToken": "HelperService",
"targetModuleName": "HelperModule",
"keyOrIndex": 0,
"injectionType": "constructor"
},
"id": "-2146943494"
},
"-2003045613": {
"source": "-377928898",
"target": "-616397055",
@@ -2296,38 +2328,6 @@
},
"id": "-881420795"
},
"-831049991": {
"source": "594986539",
"target": "-1721730431",
"metadata": {
"type": "class-to-class",
"sourceModuleName": "InputModule",
"sourceClassName": "InputService",
"targetClassName": "CircularService",
"sourceClassToken": "InputService",
"targetClassToken": "CircularService",
"targetModuleName": "CircularModule",
"keyOrIndex": 0,
"injectionType": "constructor"
},
"id": "-831049991"
},
"-2146943494": {
"source": "-234035039",
"target": "928565345",
"metadata": {
"type": "class-to-class",
"sourceModuleName": "RequestChainModule",
"sourceClassName": "RequestChainService",
"targetClassName": "HelperService",
"sourceClassToken": "RequestChainService",
"targetClassToken": "HelperService",
"targetModuleName": "HelperModule",
"keyOrIndex": 0,
"injectionType": "constructor"
},
"id": "-2146943494"
},
"-1816180282": {
"source": "-848516688",
"target": "-1673986099",