Reputation: 509
Is there any way for a method in a class decorated with @Module()
to iterate over all provider objects defined for that module?
Upvotes: 2
Views: 5006
Reputation: 483
You can access metadata by a key and module class.
For example:
console.log(Reflect.getMetadata('providers', UserModule));
Output will be like:
[class UserService], [class ConfigService] ]
Underhood, @Module
decorator looks like this:
function Module(metadata) {
const propsKeys = Object.keys(metadata);
validate_module_keys_util_1.validateModuleKeys(propsKeys);
return (target) => {
for (const property in metadata) {
if (metadata.hasOwnProperty(property)) {
Reflect.defineMetadata(property, metadata[property], target);
}
}
};
}
It defines a metadata by a property key (providers, controllers, imports and etc.) and saves it for a target (module class).
Metadata API: https://github.com/rbuckton/reflect-metadata#api
Upvotes: 3
Reputation: 509
This might not be the best solution, but at least it 'works for me'. I ended up defining all the provider classes in an array:
const MyProviders = [ ProviderClass1, ProviderClass2, ...];
Then used that constant in the module definition:
@Module({
imports: [],
providers: MyProviders,
exports: MyProviders,
controllers: []
})
export class MyModule {
I defined the constructor to include a ModuleRef
:
public constructor(private readonly moduleRef: ModuleRef) {}
And then it was a relatively simple method to iterate over the instantiated provider objects:
public someMethod(): void {
for (const cls of MyProviders) {
const provider = this.moduleRef.get(cls.name);
//
// Can now call methods, etc on provider
//
}
}
If there's a better way of doing this, I'd love to hear it.
Upvotes: 1