You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Problem statement: Everyone can create a plugin which is again a class with methods to generate a doc. Now currently if I do so I have to go to my factory and update the code there for the new plugin and in the app module too I have to go and add that as the provider. but I don't want this to be so much hassle.
Proposed solution:
some annotation over these plugin classes with tokens. I can use this token itself in the factory class to return the correct instance of the plugin. and for the app module, I can scan all the classes with my annotation and populate them in providers during runtime only. now i won't have to go and change any existing file if I add a new plugin
Use the Plugin decorator to mark your plugin classes with the corresponding token:
// pdf-plugin.tsimport{Plugin}from'./plugin.decorator';
@Plugin('pdf-plugin')exportclassPdfPlugin{generateDoc(): string{// Logic to generate a PDF documentreturn'Generated PDF document';}}
Create a factory class that will instantiate the plugins based on their tokens:
// plugin.factory.tsimport{Injectable}from'@nestjs/common';import{PLUGIN_TOKEN}from'./plugin.decorator';
@Injectable()exportclassPluginFactory{privateplugins: Map<string,any>=newMap();registerPlugin(token: string,plugin: any){this.plugins.set(token,plugin);}createPlugin(token: string): any{constplugin=this.plugins.get(token);if(!plugin){thrownewError(`Plugin not found for token: ${token}`);}returnnewplugin();}}
Scan for classes with the Plugin decorator in your app module and register them dynamically:
With this approach, we can create new plugin classes with the Plugin decorator and their respective tokens. They will be automatically discovered and registered in the PluginFactory during the runtime of your NestJS application.
createPlugin(token: string): any{constplugin=this.plugins.get(token);if(!plugin){thrownewError(`Plugin not found for token: ${token}`);}returnnewplugin();}
we are newing up the plugin instance whenever a request comes. These plugin classes should be singleton.
okay and @radhay-1199 one more question ki if a plugin class needs DI for let's say ConfigService or any other service then how are we gonna inject that or does this approach already handle that.
Activity
radhay-1199 commentedon May 28, 2023
POC:
With this approach, we can create new plugin classes with the Plugin decorator and their respective tokens. They will be automatically discovered and registered in the PluginFactory during the runtime of your NestJS application.
radhay-1199 commentedon May 28, 2023
Long term goals: Implement awilix DI for plugins with scoped lifetime management for each plugins
References- https://github.com/jeffijoe/awilix
yuvrajsab commentedon May 28, 2023
@radhay-1199 but here
we are newing up the plugin instance whenever a request comes. These plugin classes should be singleton.
AnshulMalik commentedon May 29, 2023
Looks good, agree with @yuvrajsab , let's make don't make these objects if already have one.
Now this is out of they way, we need to work on the signature of the input and output plugin methods.
radhay-1199 commentedon May 29, 2023
@yuvrajsab No actually, this map will already have beans associated with the name in them. NestJs assures that threads are singleton only.
yuvrajsab commentedon May 29, 2023
okay and @radhay-1199 one more question ki if a plugin class needs DI for let's say ConfigService or any other service then how are we gonna inject that or does this approach already handle that.