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

Missing symbol providers on dynamic modules #5964

Closed
svvac opened this issue Dec 17, 2020 · 3 comments
Closed

Missing symbol providers on dynamic modules #5964

svvac opened this issue Dec 17, 2020 · 3 comments
Labels
needs triage This issue has not been looked into

Comments

@svvac
Copy link

svvac commented Dec 17, 2020

Using provide: Symbol() with dynamic modules leads to strange behaviors and missing providers

Consider the TestModule :

@Module({})
export class TestModule {
    public static forRoot (): DynamicModule {
        return {
            module: TestModule,
            global: true,
            providers: [ { provide: 'test', useValue: { secret: 42 } } ],
            exports: [ 'test' ]
        };
    }

    public static forFeatureRandom (feature: any): DynamicModule {
        return {
            module: TestModule,
            providers: [ this.testProviderRandom(feature) ],
        };
    }

    public static forFeatureSymbol (feature: any): DynamicModule {
        return {
            module: TestModule,
            providers: [ this.testProviderSymbol(feature) ],
        };
    }

    public static forFeatureBoth (feature: any): DynamicModule {
        return {
            module: TestModule,
            providers: [ this.testProviderSymbol(feature), this.testProviderRandom(feature) ],
        };
    }


    public static testProviderRandom (feature: any): Provider {
        const provide = String(Math.random() * 0xffffff | 0);
        return {
            provide,
            inject: [ 'test' ],
            useFactory: (secret: any) => console.log('feature', feature, provide),
        }
    }

    public static testProviderSymbol (feature: any): Provider {
        const provide = Symbol(String(feature));
        return {
            provide,
            inject: [ 'test' ],
            useFactory: (secret: any) => console.log('feature', feature, provide),
        }
    }
}

With the following AppModule :

@Module({
    imports: [
        TestModule.forRoot(),
        TestModule.forFeatureSymbol(1),
        TestModule.forFeatureSymbol(2),
        TestModule.forFeatureSymbol(3),
        TestModule.forFeatureRandom(4),
        TestModule.forFeatureRandom(5),
        TestModule.forFeatureRandom(6),
        TestModule.forFeatureBoth(7),
        TestModule.forFeatureBoth(8),
        TestModule.forFeatureBoth(9),
    ],
    providers: [
        TestModule.testProviderSymbol(10),
        TestModule.testProviderSymbol(11),
        TestModule.testProviderSymbol(12),
        TestModule.testProviderRandom(13),
        TestModule.testProviderRandom(14),
        TestModule.testProviderRandom(15),
    ],
})
export class AppModule { }

Output log is :

[Nest] 3943630   - 12/17/2020, 10:23:43 AM   [NestFactory] Starting Nest application...
feature 1 Symbol(1)
feature 4 13646106
feature 5 15122973
feature 6 2519215
feature 7 Symbol(7)
feature 7 12841827
feature 8 Symbol(8)
feature 8 15527737
feature 9 Symbol(9)
feature 9 4977840
[Nest] 3943630   - 12/17/2020, 10:23:43 AM   [InstanceLoader] TestModule dependencies initialized +17ms
feature 10 Symbol(10)
feature 11 Symbol(11)
feature 12 Symbol(12)
feature 13 6085115
feature 14 14828235
feature 15 4768453
[Nest] 3943630   - 12/17/2020, 10:23:43 AM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 3943630   - 12/17/2020, 10:23:43 AM   [InstanceLoader] TestModule dependencies initialized +1ms
[Nest] 3943630   - 12/17/2020, 10:23:43 AM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 3943630   - 12/17/2020, 10:23:43 AM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 3943630   - 12/17/2020, 10:23:43 AM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 3943630   - 12/17/2020, 10:23:43 AM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 3943630   - 12/17/2020, 10:23:43 AM   [InstanceLoader] TestModule dependencies initialized +1ms
[Nest] 3943630   - 12/17/2020, 10:23:43 AM   [InstanceLoader] AppModule dependencies initialized +0ms
[Nest] 3943630   - 12/17/2020, 10:23:43 AM   [NestApplication] Nest application successfully started +5ms

Notice :

  • Features 1, 2, and 3, provided as symbols get « collapsed » into one
  • Features 4, 5 and 6, provided as random strings, work as expected
  • Features 7, 8 and 9, providing both values somehow works too
  • Features 10 to 16, not using a dynamic module work as expected too

Expected : features 2 and 3 should get loaded into nest.

Versions :

  "dependencies": {
    "@nestjs/common": "^7.6.2",
    "@nestjs/core": "^7.6.2",
    "@nestjs/platform-express": "^7.6.2",
    "reflect-metadata": "^0.1.13",
    "rxjs": "^6.6.3"
  },

edit : fixed log that did not properly match the code

@svvac svvac added the needs triage This issue has not been looked into label Dec 17, 2020
@kamilmysliwiec
Copy link
Member

Thanks for providing a great reproduction code! Fixed in 7.6.3

@svvac
Copy link
Author

svvac commented Dec 17, 2020

Tested the above code against 7.6.3, it now works as expected.

[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [NestFactory] Starting Nest application...
feature 1 Symbol(1)
feature 2 Symbol(2)
feature 3 Symbol(3)
feature 4 3573757
feature 5 1369450
feature 6 7297878
feature 7 Symbol(7)
feature 7 2868600
feature 8 Symbol(8)
feature 8 12805524
feature 9 Symbol(9)
feature 9 13922231
[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [InstanceLoader] TestModule dependencies initialized +18ms
feature 10 Symbol(10)
feature 11 Symbol(11)
feature 12 Symbol(12)
feature 13 6085400
feature 14 13402991
feature 15 12221219
[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [InstanceLoader] TestModule dependencies initialized +1ms
[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [InstanceLoader] TestModule dependencies initialized +1ms
[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [InstanceLoader] AppModule dependencies initialized +0ms
[Nest] 4137788   - 12/17/2020, 12:44:06 PM   [NestApplication] Nest application successfully started +5ms

Thanks for the quick fix!

@svvac
Copy link
Author

svvac commented Jan 7, 2021

@kamilmysliwiec After further testing the fix seems incomplete. Because the provided token gets serialized as a string, using provide: Symbol() gets serialized as "Symbol()" which leads to the same collapse as in the initial issue.

I think symbols must be kept as-is for provider tokens in order for them to be useful, since by design Symbol('abc') !== Symbol('abc')

I kindly suggest reopening this.

Adapted TestModule.testProviderSymbol()
    public static testProviderSymbol (feature: any): Provider {
        const provide = Symbol();
        return {
            provide,
            inject: [ 'test' ],
            useFactory: (secret: any) => console.log('feature', feature, provide),
        }
    }

Relevant execution logs :

[Nest] 51298   - 01/07/2021, 12:40:39 PM   [NestFactory] Starting Nest application...
feature 1 Symbol()
feature 4 6797326
feature 5 15789009
feature 6 15349412
feature 7 Symbol()
feature 7 16697338
feature 8 Symbol()
feature 8 7560964
feature 9 Symbol()
feature 9 775357
[Nest] 51298   - 01/07/2021, 12:40:39 PM   [InstanceLoader] TestModule dependencies initialized +17ms
feature 10 Symbol()
feature 11 Symbol()
feature 12 Symbol()
feature 13 4502118
feature 14 485346
feature 15 5842275
[Nest] 51298   - 01/07/2021, 12:40:39 PM   [InstanceLoader] TestModule dependencies initialized +1ms
[Nest] 51298   - 01/07/2021, 12:40:39 PM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 51298   - 01/07/2021, 12:40:39 PM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 51298   - 01/07/2021, 12:40:39 PM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 51298   - 01/07/2021, 12:40:39 PM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 51298   - 01/07/2021, 12:40:39 PM   [InstanceLoader] TestModule dependencies initialized +1ms
[Nest] 51298   - 01/07/2021, 12:40:39 PM   [InstanceLoader] TestModule dependencies initialized +0ms
[Nest] 51298   - 01/07/2021, 12:40:39 PM   [InstanceLoader] AppModule dependencies initialized +0ms
[Nest] 51298   - 01/07/2021, 12:40:39 PM   [NestApplication] Nest application successfully started +5ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage This issue has not been looked into
Projects
None yet
Development

No branches or pull requests

2 participants