Skip to main content
Version: Next

Dynamic Module Loading

1. Overview​

The system supports dynamically loading external assemblies as modules at runtime. This allows the system to add new features or replace existing implementations without recompiling the main program, serving as the foundation for plugin architecture.

2. Implementation Mechanism​

Based on .NET Core's AssemblyLoadContext and ABP Framework's module system.

2.1 Module Discovery​

The system scans specific directories (e.g., Plugins or Extensions folder) for .dll files during startup.

2.2 Assembly Loading​

Use a custom AssemblyLoadContext to load the discovered plugin assemblies to ensure resource isolation and unloadability (if supported).

2.3 Module Registration​

After loading the assembly, the system checks for classes inheriting from AbpModule. If found, they are automatically added to the application's module dependency list.

3. Configuration and Usage​

3.1 Plugin Directory Configuration​

Configure the plugin loading path in appsettings.json.

{
"Plugin": {
"Folder": "Plugins",
"Enable": true
}
}

3.2 Startup Loading Logic​

In the Program.cs or startup module configuration phase:

public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
var pluginFolder = configuration["Plugin:Folder"];

if (Directory.Exists(pluginFolder))
{
var pluginFiles = Directory.GetFiles(pluginFolder, "*.dll", SearchOption.TopDirectoryOnly);
foreach (var pluginFile in pluginFiles)
{
// Load assembly
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.GetFullPath(pluginFile));

// Register module (ABP automatically handles module scanning, or manual addition may be required depending on implementation details)
// In standard ABP, usually utilize PlugInSource
}
}
}

Using ABP's PlugInSource:

// Program.cs
await builder.AddApplicationAsync<MyHostModule>(options =>
{
options.PlugInSources.AddFolder(@"C:\MyPlugIns");
});

4. Module Dependencies​

Dynamically loaded modules can depend on the main program's shared libraries (Shared Contracts) but should avoid strong dependencies on specific implementation assemblies of the main program to maintain loose coupling.

5. Application Scenarios​

  • Multi-tenant Customization: Loading specific business modules for different tenants.
  • Feature Extension: Adding report modules, payment adapters, etc., as plugins.
  • Hot Updates: Replacing specific non-core module DLLs (requires careful handling of application lifecycle).