Plug-in System (Oglr.Plugins)

The Oglr.Plugins system enables extensibility and modularity within the Oglr project by defining a framework for adding custom functionality through plug-ins. Plug-ins can be implemented as separate assemblies, loaded dynamically, and accessed through a well-defined API. This allows developers to customize the Oglr application without modifying the core codebase, contributing to maintainability and flexibility.

Plug-in Development

  1. Implement the IPlugin Interface: All plug-ins must implement the IPlugin interface. This interface defines a single method, Initialize, which is called when the plug-in is loaded. The Initialize method provides an opportunity to register any custom functionalities, resources, or configurations required by the plug-in.

    // Oglr.Plugins/IPlugin.cs
              public interface IPlugin
              {
                  /// <summary>
                  /// Initializes the plugin.
                  /// </summary>
                  void Initialize();
              } 
              
  2. Register the Plug-in: To enable Oglr to discover and load your plug-in, you need to register it in the Oglr.Plugins.Configuration.PluginConfiguration class. This class manages the configuration of all loaded plug-ins.

    // Oglr.Plugins/Configuration/PluginConfiguration.cs
              public class PluginConfiguration
              {
                  // ... 
                  /// <summary>
                  /// Gets the list of registered plugins.
                  /// </summary>
                  public List<PluginInfo> Plugins { get; } = new List<PluginInfo>();
              
                  // ...
              }
              
  3. Create a Plug-in Assembly: The PluginInfo class in Oglr.Plugins.Configuration is used to register your plug-in. This registration requires specifying the type of the IPlugin implementation, the assembly path, and optionally a description.

    // Oglr.Plugins/Configuration/PluginInfo.cs
              public class PluginInfo
              {
                  // ...
                  public Type PluginType { get; }
              
                  /// <summary>
                  /// The path to the plugin assembly.
                  /// </summary>
                  public string AssemblyPath { get; }
              
                  /// <summary>
                  /// A description of the plugin.
                  /// </summary>
                  public string Description { get; }
              
                  // ...
              }
              

    Example:

    // ...
              // In your main application:
              var pluginConfiguration = new PluginConfiguration();
              
              // Register a plug-in:
              pluginConfiguration.Plugins.Add(new PluginInfo(
                  typeof(MyCustomPlugin), 
                  Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "MyCustomPlugin.dll"),
                  "My custom plugin"
              )); 
              

    Example:

    // Oglr.Plugins/Configuration/PluginConfiguration.cs 
              public class PluginConfiguration
              {
                  /// <summary>
                  /// Loads plugins from the specified path.
                  /// </summary>
                  public void LoadPlugins(string path)
                  {
                      // ...
                  }
              }
              
  4. Load and Initialize Plug-ins: The Oglr.Plugins system utilizes the PluginConfiguration to load and initialize all registered plug-ins. The LoadPlugins method is responsible for dynamically loading the specified assemblies and instantiating the IPlugin implementations. The Initialize method is then called for each loaded plug-in, allowing it to register its functionalities with the Oglr application.

Plug-in Usage

Once loaded and initialized, plug-ins can be accessed through the PluginManager class. This class provides methods for retrieving instances of loaded plug-ins and calling their public methods.

// Oglr.Plugins/PluginManager.cs
          public class PluginManager
          {
              // ... 
              /// <summary>
              /// Gets the plugin instance by its type.
              /// </summary>
              /// <typeparam name="TPlugin">The type of the plugin.</typeparam>
              /// <returns>The plugin instance, or null if the plugin is not loaded.</returns>
              public TPlugin GetPlugin<TPlugin>() where TPlugin : IPlugin
              {
                  // ... 
              }
              // ... 
          }
          

Example:

// ...
          // In your application:
          var pluginManager = new PluginManager(pluginConfiguration); 
          
          // Get an instance of the MyCustomPlugin:
          var myCustomPlugin = pluginManager.GetPlugin<MyCustomPlugin>();
          
          // Call methods on the MyCustomPlugin instance:
          if (myCustomPlugin != null)
          {
              myCustomPlugin.DoSomethingCustom();
          }
          

Plug-in Lifecycle

Plug-ins are loaded and initialized on application startup. They remain active throughout the application lifecycle, and can be accessed by other components through the PluginManager.

Note: Currently, there is no dedicated mechanism for unloading or de-initializing plug-ins.