AssemblyHandler Loading, NuGet & Extensions
DLL loading, NuGet package management, driver tracking, load statistics, and custom loader extensions
Source of truth (2026)
DataManagementEngineStandard/AssemblyHandler/AssemblySystem/AssemblyHandler.Core.cs.../AssemblyHandler.Loaders.cs|.Scanning.cs|.Helpers.cs.../AssemblyHandler.NuGetOperations.cs|.NuGetSources.cs.../AssemblyHandler.DriverTracking.cs|.Statistics.csDataManagementEngineStandard/AssemblyHandler/PluginSystem/SharedContextAssemblyHandler.cs
Table of Contents
API Snapshot
public interface IAssemblyHandler : IDisposable
{
List<assemblies_rep> Assemblies { get; set; }
List<Assembly> LoadedAssemblies { get; set; }
List<Type> LoaderExtensions { get; set; }
List<AssemblyClassDefinition> LoaderExtensionClasses { get; set; }
List<ILoaderExtention> LoaderExtensionInstances { get; set; }
List<AssemblyClassDefinition> DataSourcesClasses { get; set; }
// Loading
Assembly LoadAssembly(string path);
string LoadAssembly(string path, FolderFileTypes fileTypes);
IErrorsInfo LoadAllAssembly(IProgress<PassedArgs> progress, CancellationToken token);
List<Assembly> LoadAssembliesFromFolder(string folderPath,
FolderFileTypes folderFileType, bool scanForDataSources = true);
// NuGet
Task<List<NuGetSearchResult>> SearchNuGetPackagesAsync(string searchTerm,
int skip = 0, int take = 20, bool includePrerelease = false,
CancellationToken token = default);
Task<List<string>> GetNuGetPackageVersionsAsync(string packageId,
bool includePrerelease = false, CancellationToken token = default);
Task<List<Assembly>> LoadNuggetFromNuGetAsync(string packageName,
string version = null, IEnumerable<string> sources = null);
// NuGet Sources
List<NuGetSourceConfig> GetNuGetSources();
void AddNuGetSource(string name, string url, bool isEnabled = true);
void RemoveNuGetSource(string name);
List<string> GetActiveSourceUrls();
// Driver Tracking
void TrackDriverPackage(string packageId, string version,
string driverClassName, DataSourceType dsType);
List<DriverPackageMapping> GetAllDriverPackageMappings();
bool IsDriverFromNuGet(string driverClassName);
// Statistics
AssemblyLoadStatistics GetLoadStatistics();
}
DLL Loading & Scanning
Full Scan Flow
IAssemblyHandler handler = dmeEditor.assemblyHandler;
// Full discovery pass
await Task.Run(() => handler.LoadAllAssembly(progress, token));
// Targeted single DLL
var asm = handler.LoadAssembly(@"Plugins\MySourcePlugin.dll");
// Folder scan
var assemblies = handler.LoadAssembliesFromFolder(
@"Plugins", FolderFileTypes.DataSources, scanForDataSources: true);
Load Sequence
- Runtime loading — Load built-in assemblies from current app domain
- Extension discovery — Find and instantiate
ILoaderExtentionimplementations - Folder loading — Scan configured directories for plugins
- Driver scanning — Discover
IDataSourceand driver classes - Extension scans — Run each
ILoaderExtention.Scan()
FolderFileTypes
| Type | Directory |
|---|---|
DataSources | ProjectClasses/ |
Addins | Addin/ |
ConnectionDrivers | ConnectionDrivers/ |
LoadingExtensions | LoadingExtensions/ |
OtherDLL | OtherDLL/ |
AI | AI/ |
Scripts | Scripts/ |
NuGet Management
// Search
var packages = await handler.SearchNuGetPackagesAsync("postgres", take: 10);
// Versions
var versions = await handler.GetNuGetPackageVersionsAsync("Npgsql");
// Sources
handler.AddNuGetSource("my-feed", "https://my-feed/v3/index.json");
var sources = handler.GetActiveSourceUrls();
handler.RemoveNuGetSource("old-feed");
// Load from NuGet
var loaded = await handler.LoadNuggetFromNuGetAsync(
"MyCompany.CustomDataSource",
version: versions.First());
// Persistence files
// nuget_sources.json — source list and enabled flags
// driver_packages.json — driver to package/version mapping
Driver Package Tracking
Tracks which NuGet packages provide which drivers for provenance and security audit:
// Track a driver's package origin
handler.TrackDriverPackage(
packageId: "TheTechIdea.Beep.DataSources.SQLite",
version: "2.0.0",
driverClassName: "SQLiteDataSource",
dsType: DataSourceType.SqlLite);
// Query mappings
var mappings = handler.GetAllDriverPackageMappings();
foreach (var m in mappings)
Console.WriteLine($"{m.DriverClassName} ← {m.PackageId} v{m.Version}");
// Check origin
bool fromNuGet = handler.IsDriverFromNuGet("SQLiteDataSource");
// Persisted to: driver_packages.json
// Automatically loaded on startup
DriverPackageMapping
| Property | Description |
|---|---|
PackageId | NuGet package ID |
Version | Installed version |
DriverClassName | Full class name of the driver |
DataSourceType | Type of data source |
InstalledDate | When the package was installed |
Load Statistics
AssemblyHandler tracks loading performance and outcomes:
public class AssemblyLoadStatistics
{
public int TotalAssembliesLoaded { get; set; }
public TimeSpan TotalLoadTime { get; set; }
public DateTime LastLoadTimestamp { get; set; }
public int DriversFound { get; set; }
public int DataSourcesFound { get; set; }
public Dictionary<string, int> AssembliesByFolderType { get; set; }
}
// Get statistics after loading
var stats = handler.GetLoadStatistics();
Console.WriteLine($"Assemblies: {stats.TotalAssembliesLoaded}");
Console.WriteLine($"Load time: {stats.TotalLoadTime.TotalSeconds:F2}s");
Console.WriteLine($"Drivers: {stats.DriversFound}");
Console.WriteLine($"Data sources: {stats.DataSourcesFound}");
foreach (var (folder, count) in stats.AssembliesByFolderType)
Console.WriteLine($" {folder}: {count}");
Custom Loader Extensions
public sealed class CustomLoaderExtension : ILoaderExtention
{
private readonly AssemblyHandler _handler;
private readonly IConfigEditor _config;
public CustomLoaderExtension(AssemblyHandler handler)
{
_handler = handler;
_config = handler.ConfigEditor;
}
public IErrorsInfo LoadAllAssembly()
{
return _handler.ErrorObject;
}
public IErrorsInfo Scan(assemblies_rep assembly)
{
if (assembly?.DllLib != null) return Scan(assembly.DllLib);
return _handler.ErrorObject;
}
public IErrorsInfo Scan(Assembly assembly)
{
foreach (var type in assembly.GetTypes())
{
if (type.GetInterfaces().Contains(typeof(IDataSource)))
{
var cls = _handler.GetAssemblyClassDefinition(
type.GetTypeInfo(), "IDataSource");
_config.DataSourcesClasses.Add(cls);
}
}
return _handler.ErrorObject;
}
public IErrorsInfo Scan()
{
foreach (var asm in _handler.LoadedAssemblies)
Scan(asm);
return _handler.ErrorObject;
}
}
Contract name is
ILoaderExtention
The current interface spelling in the codebase is ILoaderExtention (not ILoaderExtension).
Scanned Data Contracts
During AssemblyHandler.ScanAssembly(), the handler checks these contracts and registers metadata in ConfigEditor:
// Contracts scanned by ProcessTypeInfo():
IDataSource, ILoaderExtention, IWorkFlowAction, IDM_Addin,
IWorkFlowStep, IBeepViewModel, IWorkFlowEditor, IRule,
IRuleParser, IFunctionExtension, IPrintManager, IAddinVisSchema,
IPipelinePlugin, IFileFormatReader, IDefaultValueResolver
Usage Examples
Complete Startup
var handler = editor.assemblyHandler;
// Load all assemblies with progress
var progress = new Progress<PassedArgs>(args =>
Console.WriteLine($"[{args.ParameterInt1}%] {args.Messege}"));
handler.LoadAllAssembly(progress, CancellationToken.None);
// Check results
var stats = handler.GetLoadStatistics();
Console.WriteLine($"Loaded {stats.TotalAssembliesLoaded} assemblies " +
$"in {stats.TotalLoadTime.TotalSeconds:F1}s");
Console.WriteLine($"Found {stats.DataSourcesFound} data sources, " +
$"{stats.DriversFound} drivers");
NuGet Driver Installation
// Search for PostgreSQL driver
var packages = await handler.SearchNuGetPackagesAsync("postgresql", take: 5);
// Get latest version
var version = (await handler.GetNuGetPackageVersionsAsync(
packages[0].PackageId)).First();
// Install and load
var assemblies = await handler.LoadNuggetFromNuGetAsync(
packages[0].PackageId, version);
// Track provenance
handler.TrackDriverPackage(
packages[0].PackageId, version,
"PostgreDataSource", DataSourceType.Postgresql);
Error Handling
var result = handler.LoadAllAssembly(progress, token);
if (result.Flag != Errors.Ok)
{
Console.WriteLine($"Load failed: {result.Message}");
if (result.Ex != null)
Console.WriteLine($"Exception: {result.Ex.Message}");
}
// Check for load errors
if (handler.HasLoadErrors)
{
foreach (var error in handler.LoadErrors)
Console.WriteLine($"Load Error: {error}");
}
Complete Source File Map (31 files)
AssemblySystem (8 files)
| File | Content |
|---|---|
AssemblyHandler.Core.cs | Constructor, fields, Initialize, 16 primary arrays (ScannedDataSources, LoadedAssembliesCompact, etc.) |
AssemblyHandler.Loaders.cs | Extension loader discovery, ILoaderExtention/ILoaderExtention2, priority-sorted load, LoadExtensionTypes |
AssemblyHandler.Scanning.cs | ScanAllAssemblies, ScanFolder, ProcessAssembly, manifest-based type scanning |
AssemblyHandler.Helpers.cs | Type filtering, LoadAssemblySafe, logging helpers |
AssemblyHandler.NuGetOperations.cs | NuGet package resolution via NuGetPackageManager, driver download/install |
AssemblyHandler.NuGetLifecycle.cs | NuGet load/unload with SharedContext vs isolated ALC |
AssemblyHandler.NuGetSources.cs | NuGet source management: nuget_sources.json, add/remove/enable/disable |
AssemblyHandler.DriverTracking.cs | Driver scan tracking: scanned drivers, version checks, upgrade hints |
AssemblyHandler.Statistics.cs | Load statistics, assembly count, type count, duration tracking |
PluginSystem (21 files)
| File | Content |
|---|---|
SharedContextAssemblyHandler.cs | Shared-ALC assembly loading with type sharing across plugins |
SharedContextManager.cs | Context lifecycle: create, dispose, type resolution across contexts |
SharedAssemblyTracker.cs | Tracks which assemblies are loaded in shared vs isolated contexts |
PluginRegistry.cs | Central plugin registration: discover, register, unregister |
PluginManifest.cs | Plugin manifest model: Id, Name, Version, Dependencies, EntryPoint |
PluginLifecycleManager.cs | Plugin lifecycle: Load, Initialize, Execute, Unload, Dispose |
PluginHealthMonitor.cs | Plugin health checks: heartbeat, timeout detection, auto-restart |
PluginIsolationManager.cs | AssemblyLoadContext isolation: separate ALC per plugin when needed |
PluginVersionManager.cs | Version compatibility checks, dependency version resolution |
PluginServiceManager.cs | DI service registration for plugins: IPluginServiceProvider |
PluginMessageBus.cs | In-process pub/sub between plugins: publish, subscribe, unsubscribe |
PluginProcessManager.cs | Out-of-process plugin hosting (IPC) for isolation |
PluginInstaller.cs | Plugin installation from NuGet: download, extract, register |
NuggetPluginLoader.cs | Load plugins from installed NuGet packages |
NuggetPackageDownloader.cs | Downloads NuGet plugin packages via NuGetPackageManager |
NuggetManager.cs | Aggregate NuGet package tracking for the PluginSystem |
AssemblyScanningAssistant.cs | Scans assemblies for plugin types (IDM_Addin, IDataSource) |
AssemblyLoadingAssistant.cs | Safe assembly loading with error isolation per assembly |
DriverDiscoveryAssistant.cs | Discovers IDataSource / ConnectionDriversConfig types |
InstanceCreationAssistant.cs | Creates instances from discovered types with DI support |
UnloadAnalysis.cs | Analyzes assembly dependencies before unload to prevent dangling refs |
IScanningService.cs | Scanning service contract: ScanFolder, ScanAssembly, ScanPackage |
NuggetManager
public class NuggetManager
{
// Aggregate NuGet package tracking for the PluginSystem
public NuggetManager(IDMLogger logger, string packagesDirectory);
public List<string> InstalledPackageIds { get; }
public Task<bool> InstallAsync(string packageId, string version = null);
public Task<bool> UninstallAsync(string packageId);
public Task<bool> UpdateAsync(string packageId, string version);
public Task<List<string>> GetOutdatedPackagesAsync();
}