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