Skip to content

Docs: Plugin

ng-druid edited this page Aug 8, 2025 · 1 revision

Documentation for Angular Plugin Library

Table of Contents

  1. Introduction
  2. Installation
  3. Overview of Components and Services
    • PluginModule
    • Models (plugin.models.ts)
    • Services
  4. Usage
    • Define and Register Plugins
    • Plugin Discovery
    • Plugin Configuration Management
    • Dynamic Loading of Plugins
  5. API Reference
  6. Examples
  7. Testing
  8. Key Concepts

1. Introduction

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.


2. Installation

Install the library using your package manager:

npm install @your-org/plugin

3. Overview of Components and Services

3.1 PluginModule (Lazy-Loading Module)

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 { }

3.2 Models (Defined in plugin.models.ts)

Models include interfaces and classes that represent plugins, configurations, and plugin definitions.

  • PluginManager
    Manages plugin operations like register, 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 like id and title.

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>;
}

3.3 Services

  • 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.
      }
    }

4. Usage

4.1 Define and Register 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);

4.2 Plugin Discovery

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
});

4.3 Plugin Configuration Management

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);

4.4 Dynamic Loading of Plugins

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');
    }
  });

5. API Reference

Classes

  • Plugin<T>
  • PluginConfig
  • PluginConfigModule
  • PluginDef

Interfaces

  • PluginManager
  • PluginDiscovery

Services

  • PluginConfigurationManager
  • ConfigDiscovery

Abstract Classes

  • BasePluginManager

6. Examples

  • Basic Plugin Registration
  • Dynamic Plugin Loading
  • Custom PluginManager Implementation

Refer to the example directory for detailed code samples (/examples).


7. Testing

Tests are configured via Karma and written with Jasmine. Use the following command to run tests:

npm run test

The src/test.ts sets up the Angular testing environment.


8. Key Concepts

  • Plugin Modularity: Decouple plugin implementations to maintain modularity.
  • Dynamic Loading: Use Angular's Compiler module to load plugins at runtime to reduce the initial application size.
  • Discovery Pipeline: Create a flexible, extendable discovery mechanism for plugins.

Conclusion

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!

Clone this wiki locally