Working with Modules

A module is an object that represents a loaded plugin module. Hydra provides a separate module object for each plugin type, but in most cases you will use THYModule for VCL or THYBaseModule for FireMonkey.

Getting a Module

THYModuleManager provides a couple of methods and properties that allow you to work with modules:

  • property ModuleCount - Returns the number of modules loaded by the module manager.
  • property Modules[Index] - Returns a reference to the module with the specified index.
  • FindModule(FileName) - Searches for the module with the specified file name, if none are found, nil is returned.
  • ModuleByFileName(FileName) - Searches for the module with the specified file name, if none are found, an exception is thrown.

In addition module manager provides the OnAfterLoadModule that allows you to pass a reference to a module that was loaded:

ModuleManager.OnAfterLoadModule := AfterLoadModule;
ModuleManager.LoadModule('Plugin.dll');

procedure TMainForm.AfterLoadModule(Sender: THYModuleManager; aModule: THYModule);
begin
  ShowMessage(aModule.FileName);
end;

Using Modules

THYModule allows you to access the following data:

  • property FileName - File name of the plugin module.
  • property Handle - Returns the handle of the loaded module. This property may not provide data for modules that do not have a proper handle (i.e. Silverlight).
  • property Assembly - This property is available in the THYManagedModule. Allows you to access the assembly object of a loaded managed plugin module.
  • property Controller - Returns a reference to the THYManagedModuleController.

One of the most important elements here is the reference to the module controller. The controller is a singleton object that is created when the module is loaded. It provides access to a list of plugin descriptors (which will be described later in this article) and allows the host application to interact with the plugin module with the help of custom interfaces.

For example:

var
  Intf: IMyCustomInterface;
begin
  if Supports(ModuleManager.Modules[0].ModuleController, IMyCustomInterface, Intf) then
    Intf.DoSomething;
end;

If you need more info on how to use custom interfaces, please refer to this article: Passing interfaces between Host and Plugins.

If you use managed or VCL plugin modules, the module controller also allows you to access a shared image list by using the following properties:

  • property SmallImages
  • property LargeImages

This allows you to easily share images between host and plugins.

Working with Plugin Descriptors

The plugin descriptor is an object that holds information about a plugin that is stored in a module. Similar to modules, there are several descriptor types; the most commonly used is the base THYPluginDescriptor (for FireMonkey THYCrossPlatformPluginDescriptor) class.

Getting a Descriptor

There are two ways to get a plugin descriptor. The first is to use the THYModuleManager that provides access to all descriptors from all loaded modules; the second is to use an individual module and access the descriptors by using the module controller.

Both module manager and module controller provide the following properties that allow you to access descriptors:

  • property PluginDescriptorCount - Returns the number of plugin descriptors.
  • property PluginDescriptors[Index] - Returns a reference to the THYPluginDescriptor by specified index.

In addition, module manager provides these methods:

  • FindPluginDescriptor(Name) - Searches for a plugin descriptor with a specified name, if none are found, nil is returned.
  • PluginDescriptorByName(Name) - Searches for a plugin descriptor with a specified name, if none are found, an exception is thrown.
ModuleManager.OnAfterLoadModule := AfterLoadModule;
ModuleManager.LoadModule('Plugin.dll');

ShowMessage(ModuleManager.PluginDescriptorByName('Plugin1').Description);

procedure TMainForm.AfterLoadModule(Sender: THYModuleManager; aModule: THYModule);
begin
  ShowMessage(aModule.ModuleController.PluginDescriptors[0].Description);
end;

Using Plugin Descriptors

Plugin descriptors allow you to access the meta-data of a plugin:

  • property Name - Name of the plugin. This name is used to create an instance of the plugin.
  • property PluginType - Enum that represents the type of the plugin.
  • property MajorVersion/MinorVersion - Version of the plugin.
  • property Description - Returns a string that represents the plugin description.
  • property UserData - String with custom defined data.
  • property RequiredPrivilege - Custom security token of the plugin.

Please note that all these fields (except for Name and PluginType) are optional.

In addition, it provides three methods that allow to perform different checks:

  • CheckPluginInterface(GUID) - Allows to check whether the plugin supports the specified interface.
  • CheckPluginType(String) - Checks if the plugin is inherited from a specified type.
  • CheckPluginAttribute(String) - For a managed plugin THYManagedPluginDescriptor, allows to check the plugin attribute.

These methods allow you to perform specific checks before actually creating a plugin instance, for example:

var
  Desc: THYPluginDescriptor;
begin
  ModuleManager.LoadModule('Plugin.dll');
  Desc := ModuleManager.FindPluginDescriptor('Plugin1');

  if Desc.CheckPluginInterface(IMyCustomInterface) then
    ModuleManager.CreateInstance(Desc.Name, Instance);