- 
                Notifications
    
You must be signed in to change notification settings  - Fork 1
 
Docs: Plugin
- Introduction
 - Installation
 - 
Overview of Components and Services
PluginModule- Models (
plugin.models.ts) - Services
 
 - 
Usage
- Define and Register Plugins
 - Plugin Discovery
 - Plugin Configuration Management
 - Dynamic Loading of Plugins
 
 - API Reference
 - Examples
 - Testing
 - Key Concepts
 
This Angular library (plugin) simplifies the management of plugins by supporting plugin discovery, dynamic loading, and configuration. The framework aims to enable modularity and flexibility within Angular applications by decoupling plugin implementations from their consumption.
Install the library using your package manager:
npm install @your-org/plugin
The PluginModule serves as the root Angular module for this library. It imports utility modules like UtilsModule from external dependencies such as @rollthecloudinc/utils.
import { NgModule } from '@angular/core';
import { UtilsModule } from '@rollthecloudinc/utils';
@NgModule({
  declarations: [],
  imports: [UtilsModule],
  exports: []
})
export class PluginModule { }Models include interfaces and classes that represent plugins, configurations, and plugin definitions.
- 
PluginManager
Manages plugin operations likeregister,discovery, and fetching plugins. - 
PluginDiscovery
Handles dynamic plugin loading. - 
PluginConfig
Manages plugin module configurations, such as registered modules and plugins. - 
PluginDef
Represents metadata about a plugin, like its name. - 
Plugin
Acts as a base class for a plugin. It includes properties likeidandtitle. 
export interface PluginManager<T extends Plugin<Y>, Y> {
  discovery(): void;
  pluginDef(): Observable<PluginDef>;
  register(plugin: T): void;
  getPlugins(names?: Array<Y>): Observable<Map<Y, T>>;
  getPlugin(name: Y): Observable<T>;
}- 
PluginConfigurationManager
Handles the registration and retrieval of plugin configurations.@Injectable({ providedIn: 'root' }) export class PluginConfigurationManager { private configs: Array<PluginConfig> = []; addConfig(cfg: PluginConfig) { this.configs.push(cfg); } getConfigs(): Array<PluginConfig> { return this.configs; } }
 - 
ConfigDiscovery
Dynamically resolves and loads plugins based on a provided configuration and plugin definition.@Injectable({ providedIn: 'root' }) export class ConfigDiscovery implements PluginDiscovery { constructor( private pcm: PluginConfigurationManager, private moduleLoader: ModuleLoaderService ) {} loadPlugins(pluginDef: PluginDef, ids: Array<any> = []): Observable<boolean> { // Logic to load plugins dynamically } }
 - 
BasePluginManager
Abstract base class to manage plugin discovery and registration pipelines.export abstract class BasePluginManager<T extends Plugin<Y>, Y> { protected pluginInstances = new Map<Y, T>(); private discoveryPipeline: Array<PluginDiscovery> = []; abstract pluginDef(): Observable<PluginDef>; discovery() { this.discoveryPipeline.push(new ConfigDiscovery(this.pcm, this.moduleLoader)); } register(plugin: T): void { this.pluginInstances.set(plugin.id, plugin); } getPlugins(ids?: Array<Y>): Observable<Map<Y, T>> { // Logic for retrieving registered plugins. } }
 
You can define plugins by creating classes that extend the Plugin base model. Use BasePluginManager or create a custom Service to register your plugins.
export class MyPlugin extends Plugin<string> {
  constructor(data?: Partial<MyPlugin>) {
    super(data);
  }
}
// Instantiating and registering a plugin
const pluginInstance = new MyPlugin({ id: 'plugin1', title: 'My First Plugin' });
pluginManager.register(pluginInstance);Discovery occurs via the ConfigDiscovery service, which uses information registered in PluginConfigurationManager.
pluginManager.getPlugins(['plugin1']).subscribe((plugins) => {
  console.log(plugins); // A map containing the plugin instance
});Configurations are handled using PluginConfig and PluginConfigurationManager. Define your plugin modules and register them.
const config = new PluginConfig({
  modules: [
    new PluginConfigModule({
      module: () => import('./my-plugin.module').then(m => m.MyPluginModule),
      plugins: new Map([['my-plugin', ['plugin1', 'plugin2']]])
    })
  ]
});
pluginConfigurationManager.addConfig(config);Dynamic loading leverages Angular's Compiler and the ModuleLoaderService (provided by @rollthecloudinc/utils) for runtime plugin management.
configDiscovery.loadPlugins(new PluginDef({ name: 'my-plugin' }), ['plugin1'])
  .subscribe((isLoaded) => {
    if (isLoaded) {
      console.log('Plugins loaded successfully');
    }
  });Plugin<T>PluginConfigPluginConfigModulePluginDef
PluginManagerPluginDiscovery
PluginConfigurationManagerConfigDiscovery
BasePluginManager
- Basic Plugin Registration
 - Dynamic Plugin Loading
 - Custom PluginManager Implementation
 
Refer to the example directory for detailed code samples (/examples).
Tests are configured via Karma and written with Jasmine. Use the following command to run tests:
npm run testThe src/test.ts sets up the Angular testing environment.
- Plugin Modularity: Decouple plugin implementations to maintain modularity.
 - 
Dynamic Loading: Use Angular's 
Compilermodule to load plugins at runtime to reduce the initial application size. - Discovery Pipeline: Create a flexible, extendable discovery mechanism for plugins.
 
This Angular plugin library provides a comprehensive system for managing modular, dynamic plugins in Angular applications. Whether you're building extensible enterprise apps or modular feature sets, this library is versatile enough to adapt to your needs.
Let us know if you need additional customization or features!