feat(core): introduce entry providers concept

This commit is contained in:
Kamil Myśliwiec
2023-02-10 10:58:37 +01:00
parent 7a90b7c9b4
commit a2b3e1b727
3 changed files with 44 additions and 12 deletions

View File

@@ -1,4 +1,7 @@
import { EnhancerSubtype } from '@nestjs/common/constants';
import {
EnhancerSubtype,
ENTRY_PROVIDER_WATERMARK,
} from '@nestjs/common/constants';
import {
ClassProvider,
Controller,
@@ -61,7 +64,9 @@ export class Module {
InstanceToken,
InstanceWrapper<Controller>
>();
private readonly _entryProviderKeys = new Set<InstanceToken>();
private readonly _exports = new Set<InstanceToken>();
private _distance = 0;
private _initOnPreview = false;
private _isGlobal = false;
@@ -148,6 +153,12 @@ export class Module {
return this._controllers;
}
get entryProviders(): Array<InstanceWrapper<Injectable>> {
return Array.from(this._entryProviderKeys).map(token =>
this.providers.get(token),
);
}
get exports(): Set<InstanceToken> {
return this._exports;
}
@@ -258,8 +269,12 @@ export class Module {
): Provider | InjectionToken;
public addProvider(provider: Provider, enhancerSubtype?: EnhancerSubtype) {
if (this.isCustomProvider(provider)) {
if (this.isEntryProvider(provider.provide)) {
this._entryProviderKeys.add(provider.provide);
}
return this.addCustomProvider(provider, this._providers, enhancerSubtype);
}
this._providers.set(
provider,
new InstanceWrapper({
@@ -273,6 +288,11 @@ export class Module {
host: this,
}),
);
if (this.isEntryProvider(provider)) {
this._entryProviderKeys.add(provider);
}
return provider as Type<Injectable>;
}
@@ -349,10 +369,12 @@ export class Module {
if (isUndefined(durable)) {
durable = isDurable(useClass);
}
const token = provider.provide;
collection.set(
provider.provide,
token,
new InstanceWrapper({
token: provider.provide,
token,
name: useClass?.name || useClass,
metatype: useClass,
instance: null,
@@ -632,6 +654,12 @@ export class Module {
};
}
private isEntryProvider(metatype: InjectionToken): boolean {
return typeof metatype === 'function'
? !!Reflect.getMetadata(ENTRY_PROVIDER_WATERMARK, metatype)
: false;
}
private generateUuid(): string {
const prefix = 'M_';
const key = this.name?.toString() ?? this.token?.toString();