Services Registration & Lifetimes

How to configure and register BeepService with Microsoft Dependency Injection for desktop, web, Blazor, and CLI applications.

Location: TheTechIdea.Beep.Container.Services — DataManagementEngineStandard/Services/.

Overview

BeepService is the top-level container that wires together all core BeepDM components (IDMEEditor, IConfigEditor, IAssemblyHandler, etc.) and exposes them through a single IBeepService interface suitable for dependency injection.

⚠ Accuracy notice — the AddBeepFor* platform shortcuts are not implemented.

Large parts of this page describe a platform-shortcut layer — AddBeepForDesktop, AddBeepForWeb, AddBeepForBlazorServer, AddBeepForBlazorWasm, AddBeepForMaui — together with DesktopBeepOptions, WebBeepOptions and BlazorBeepOptions. None of these exist in the current codebase. They appear only inside commented-out sketches under DataManagementEngineStandard/Services/Examples/. Treat every AddBeepFor* sample below as a proposed API, not a working one — it will not compile.

What the platform files (BeepServiceExtensions.Desktop/Web/Blazor/Maui.cs) actually contain is the logging and audit preset pairs (AddBeepLoggingForDesktop / AddBeepAuditForDesktop, and the Web, Blazor and MAUI equivalents). Those are real — see BeepService → Service Extensions.

For registration today, use the fluent builder or the options delegate, and set the lifetime explicitly with AsSingleton() / AsScoped():

// Desktop equivalent of the proposed AddBeepForDesktop()
IBeepService beep = services.AddBeepServices()
    .WithDirectory(AppContext.BaseDirectory)
    .WithAppRepo("MyApp")
    .WithConfigType(BeepConfigType.Application)
    .WithMapping()
    .WithAssemblyLoading()
    .AsSingleton()          // .AsScoped() for web / Blazor Server
    .Build();

// Optional, and genuinely available:
services.AddBeepLoggingForDesktop("MyApp");
services.AddBeepAuditForDesktop("MyApp");

The services layer provides these registration styles:

StyleAPIStatusBest for
Fluent builderAddBeepServices().WithDirectory(…).AsSingleton().Build()✅ AvailableIntelliSense-driven, method-chained setup — recommended
Options patternAddBeepServices(Action<BeepServiceOptions>)✅ AvailableFine-grained cross-platform control
Legacy simpleRegister(services, path, name, configType)✅ AvailableBackward compatibility only
Directnew BeepService(services) + Configure(…)✅ AvailableNo DI container / full manual control
Platform shortcutsAddBeepForDesktop, AddBeepForWeb, AddBeepForBlazorServer, AddBeepForBlazorWasm❌ Not implementedProposed only — see the notice above

Files in this module

FilePurpose
BeepService.csCore IBeepService implementation
RegisterBeepinServiceCollection.csCore DI registration, fluent builder, options, validation exceptions
BeepServiceExtensions.Desktop.csAddBeepLoggingForDesktop, AddBeepAuditForDesktop
BeepServiceExtensions.Web.csAddBeepLoggingForWeb, AddBeepAuditForWeb
BeepServiceExtensions.Blazor.csAddBeepLoggingForBlazor, AddBeepAuditForBlazor (require an IIndexedDbBridge)
BeepServiceExtensions.Maui.csAddBeepLoggingForMaui, AddBeepAuditForMaui (require an app-data directory provider)
BeepServiceExtensions.Logging.csAddBeepLogging + LoggingPipelineKey
BeepServiceExtensions.Audit.csAddBeepAudit + AuditPipelineKey
BeepServiceExtensions.AddinDiscovery.csAddBeepViews, AddBeepViewModels, discovery hook events
BeepServiceExtensions.DataSources.csAddDataSourceDriver overloads
BeepServiceExtensions.Retention.csAddBeepBudgetEnforcer, AddBeepRetentionSweeper
BeepServiceExtensions.Schema.csAddBeepSchemaManager
BeepServiceExtensions.EntityDiscovery.csAddBeepEntityDiscovery
BeepServiceExtensions.Diagnostics.csinternal — diagnostics attachment and metrics snapshot
BeepConnectionRepository.csScope/profile-aware connection catalog wired in by Configure()
IConnectionStorageProvider.cs, JsonConnectionStorageProvider.csPluggable connection storage backend
ConnectionHealthMonitor.csOpt-in connection health polling and reconnect
EnvironmentService.csPlatform folder creation and mapping helpers
ServiceCollectionExtensions.csLow-level JsonLoader / DMEEditor registrations
ServiceHelper.csStatic service-locator helper (use sparingly)

BeepService

BeepService implements IBeepService and IDisposable. It creates and owns all core BeepDM component instances during Configure().

Properties

PropertyTypeDescription
DMEEditorIDMEEditorCentral data management orchestrator
Config_editorIConfigEditorConnection and mapping configuration
lgIDMLoggerLogger instance
utilIUtilUtility helpers
ErinfoIErrorsInfoError tracking object
jsonLoaderIJsonLoaderJSON serialisation service
LLoaderIAssemblyHandlerPlugin / assembly loader
ServicesIServiceCollectionDI container (null if instantiated directly)
AppRepoNamestringContainer / application repository name
ConfigureationTypeBeepConfigTypeActive configuration mode
BeepDirectorystringRoot directory for Beep data files
ContainernamestringObsolete Use AppRepoName

Configure()

Initialises all components. Called automatically by the DI registration helpers or manually for direct instantiation.

// Direct instantiation (no DI):
var beep = new BeepService();
beep.Configure(
    directorypath: AppContext.BaseDirectory,
    containername: "MyApp",
    configType: BeepConfigType.DataConnector,
    AddasSingleton: false
);

Initialisation order inside Configure():

  1. Sets AppRepoName, ConfigureationType, BeepDirectory
  2. Creates ErrorsInfo, DMLogger, JsonLoader
  3. Creates ConfigEditor (reads JSON configs from {BeepDirectory}/Beep)
  4. Creates Util, AssemblyHandler, DMEEditor
  5. Optionally registers all instances into IServiceCollection (singleton or scoped)
  6. Calls LoadConfigurations() — loads data-source configs, mappings

LoadServicesScoped() / LoadServicesSingleton()

// Called automatically by Configure(); exposed for advanced scenarios
beep.LoadServicesSingleton();  // registers IDMLogger, IConfigEditor, IDMEEditor, IUtil, IJsonLoader, IAssemblyHandler
beep.LoadServicesScoped();     // registers same interfaces using AddKeyedScoped

BeepServiceOptions

The canonical options object used by all registration helpers.

PropertyTypeDefaultDescription
DirectoryPathstringAppContext.BaseDirectoryRoot directory for Beep data storage
AppRepoNamestring"BeepApp"Logical application / container name
ConfigTypeBeepConfigTypeApplicationConfiguration storage mode
ServiceLifetimeServiceLifetimeSingletonDI lifetime (overridden by platform helpers)
EnableAutoMappingbooltrueCreates type mappings at startup
EnableAssemblyLoadingbooltrueScans and loads driver/addin assemblies
InitializationTimeoutTimeSpan5 minMaximum wait for async initialization
EnableConfigurationValidationbooltrueValidates options before startup
AdditionalPropertiesDictionary<string,object>emptyPlatform-specific extension values

Validation Exceptions

ExceptionWhen thrownKey properties
BeepServiceValidationExceptionConfiguration validation failsPropertyName, InvalidValue
BeepServiceStateExceptionRuntime state is invalidComponentName

Desktop Registration

⚠ Proposed API — not implemented. Everything in this section (AddBeepForDesktop, DesktopBeepOptions) is a design sketch that does not exist in the codebase and will not compile. For a desktop app today, use services.AddBeepServices().WithDirectory(…).WithAppRepo(…).AsSingleton().Build().

The proposal was for AddBeepForDesktop to cover WinForms, WPF, and any long-running desktop process, always registering as Singleton.

DesktopBeepOptions

PropertyDefaultDescription
DirectoryPathAppContext.BaseDirectoryRoot data directory
AppRepoName"DesktopApp"Container name
ConfigTypeApplicationConfig mode
EnableAutoMappingtrueMaps at startup
EnableAssemblyLoadingtrueScans plugins
EnableProgressReportingtrueEnables UI progress hooks
EnableDesignTimeSupporttrueSupports VS designers
AutoInitializeFormsfalseAuto-init forms on startup
InitializationTimeout5 minMax startup wait

Registration

// In Program.cs (WinForms / WPF with IHost):
var host = Host.CreateDefaultBuilder(args)
    .ConfigureServices((context, services) =>
    {
        services.AddBeepForDesktop(opts =>
        {
            opts.DirectoryPath = AppContext.BaseDirectory;
            opts.AppRepoName = "MyDesktopApp";
            opts.EnableProgressReporting = true;
            opts.EnableAutoMapping = true;
            opts.EnableAssemblyLoading = true;
        });
    })
    .Build();

// Resolve after host is built:
var beepService = host.Services.GetRequiredService<IBeepService>();

With Progress Reporting

var progress = new Progress<PassedArgs>(args =>
{
    Console.WriteLine($"[{args.EventType}] {args.Messege}");
});

// If your desktop extension surfaces a UseBeepForDesktop method:
var beepService = host.UseBeepForDesktop(progress);
Desktop always forces ServiceLifetime.Singleton — the lifetime in BeepServiceOptions is overridden automatically by DesktopBeepOptions.ToBeepServiceOptions().

Web / ASP.NET Core Registration

⚠ Proposed API — not implemented. AddBeepForWeb, WebBeepOptions and the app.UseBeepForWeb() middleware do not exist in the codebase. There is no Beep-supplied ASP.NET Core middleware at all. For a web app today, use builder.Services.AddBeepServices().WithDirectory(…).WithAppRepo(…).AsScoped().Build().

The proposal was for AddBeepForWeb to cover ASP.NET Core Web API and MVC applications, always registering as Scoped (one instance per HTTP request).

WebBeepOptions

PropertyDefaultDescription
DirectoryPath{BaseDir}/BeepRoot data directory
AppRepoName"WebApp"Container name
EnableAutoMappingtrueMaps at startup
EnableAssemblyLoadingtrueScans plugins
EnableRequestIsolationtrueIsolates state per HTTP request
EnableConnectionPoolingtrueReuses connections across requests
EnableApiDiscoveryfalseAuto-discovers BeepService API endpoints
InitializationTimeout5 minMax startup wait

Registration & Middleware

// Program.cs — options pattern
builder.Services.AddBeepForWeb(opts =>
{
    opts.DirectoryPath = Path.Combine(builder.Environment.ContentRootPath, "Beep");
    opts.AppRepoName = "MyWebApi";
    opts.EnableConnectionPooling = true;
    opts.EnableRequestIsolation = true;
});

var app = builder.Build();
app.UseBeepForWeb();   // Registers connection cleanup middleware
app.MapControllers();
app.Run();

Fluent Builder (Web)

builder.Services.AddBeepForWeb()
    .InDirectory(Path.Combine(basePath, "Beep"))
    .WithAppRepo("MyWebApi")
    .WithConnectionPooling()
    .WithRequestIsolation()
    .WithApiDiscovery()
    .WithMapping()
    .Build();

Controller Injection Example

[ApiController]
[Route("api/[controller]")]
public class DataSourceController : ControllerBase
{
    private readonly IBeepService _beep;
    public DataSourceController(IBeepService beep) => _beep = beep;

    [HttpGet("list")]
    public IActionResult GetDataSources()
    {
        var sources = _beep.DMEEditor.DataSources
            .Select(ds => new { ds.DatasourceName, Type = ds.DatasourceType.ToString() });
        return Ok(sources);
    }
}

Blazor Registration

⚠ Proposed API — not implemented. AddBeepForBlazorServer, AddBeepForBlazorWasm and BlazorBeepOptions do not exist in the codebase. Use AddBeepServices() with AsScoped() for Blazor Server and AsSingleton() for Blazor WebAssembly.

What is real in BeepServiceExtensions.Blazor.cs is the logging/audit pair AddBeepLoggingForBlazor(IIndexedDbBridge bridge, …) and AddBeepAuditForBlazor(IIndexedDbBridge bridge, …) — both require an IIndexedDbBridge for browser-side storage.

The proposal was for two separate extension methods covering the two Blazor hosting models.

BlazorBeepOptions

PropertyDefaultDescription
DirectoryPath{BaseDir}/BeepRoot data directory
AppRepoName"BlazorApp"Container name
ServiceLifetimeSet per methodScoped (Server) or Singleton (WASM)
EnableSignalRProgressfalseReal-time progress via SignalR (Server)
UseBrowserStoragefalseBrowser localStorage/sessionStorage (WASM)
EnableCircuitHandlersfalseCircuit lifecycle hooks (Server)
EnableAutoMappingtrueMaps at startup
EnableAssemblyLoadingtrueScans plugins

Blazor Server

// Program.cs — Blazor Server
builder.Services.AddBeepForBlazorServer(opts =>
{
    opts.DirectoryPath = Path.Combine(builder.Environment.ContentRootPath, "Beep");
    opts.AppRepoName = "MyBlazorServerApp";
    opts.EnableSignalRProgress = true;    // real-time progress via SignalR
    opts.EnableCircuitHandlers = true;    // cleanup on circuit disconnect
});
// Lifetime = Scoped (one per Blazor circuit)

Blazor WebAssembly

// Program.cs — Blazor WASM
builder.Services.AddBeepForBlazorWasm(opts =>
{
    opts.DirectoryPath = "Beep";          // browser virtual path
    opts.AppRepoName = "MyBlazorWasmApp";
    opts.UseBrowserStorage = true;        // persist config in localStorage
});
// Lifetime = Singleton (WASM has single user per process)

Blazor Component Usage

@inject IBeepService BeepService
@inject IJSRuntime JSRuntime

@code {
    private List<string> dataSources = new();

    protected override async Task OnInitializedAsync()
    {
        var ds = BeepService.DMEEditor.GetDataSource("mydb");
        if (ds != null)
        {
            var entities = await Task.Run(() => ds.GetEntities("", new List<ReportFilter>()));
            dataSources = entities.Select(e => e.EntityName).ToList();
        }
    }
}

Fluent Builder API

AddBeepServices() (no arguments) returns an IBeepServiceBuilder for method-chained configuration. This provides the best IntelliSense experience and is platform-agnostic.

IBeepServiceBuilder Methods

MethodDescription
WithDirectory(path)Sets DirectoryPath
WithAppRepo(name)Sets AppRepoName
WithConfigType(type)Sets ConfigType
WithMapping(enable)Enables/disables auto mapping
WithAssemblyLoading(enable)Enables/disables plugin scanning
WithTimeout(timeSpan)Sets initialization timeout
WithValidation(enable)Enables/disables startup validation
WithProperty(key, value)Adds an entry to AdditionalProperties
AsSingleton()Registers as Singleton lifecycle
AsScoped()Registers as Scoped lifecycle
AsTransient()Registers as Transient lifecycle
Build()Completes registration and returns IBeepService

Usage

// Desktop (singleton)
services.AddBeepServices()
    .WithDirectory(AppContext.BaseDirectory)
    .WithAppRepo("MyApp")
    .WithConfigType(BeepConfigType.Application)
    .WithMapping()
    .WithAssemblyLoading()
    .AsSingleton()
    .Build();

// Web (scoped)
services.AddBeepServices()
    .WithDirectory(Path.Combine(basePath, "Beep"))
    .WithAppRepo("MyWebApi")
    .WithProperty("EnableConnectionPooling", true)
    .AsScoped()
    .Build();

Options Pattern (alternative)

IBeepService beep = services.AddBeepServices(opts =>
{
    opts.DirectoryPath = AppContext.BaseDirectory;
    opts.AppRepoName = "MyApp";
    opts.ConfigType = BeepConfigType.DataConnector;
    opts.ServiceLifetime = ServiceLifetime.Singleton;
    opts.EnableAutoMapping = true;
    opts.EnableAssemblyLoading = true;
});

Legacy Registration API

Register() is preserved for backward compatibility. Prefer the platform-specific helpers for new code.

// Backward-compatible simple registration
IBeepService beep = services.Register(
    directoryPath: AppContext.BaseDirectory,
    containerName: "MyApp",
    configType: BeepConfigType.DataConnector,
    addAsSingleton: true
);

EnvironmentService

EnvironmentService is a static helper that resolves platform-appropriate data folder paths and populates BeepDM mapping configurations. It is called internally by BeepService.Configure() but can also be used directly.

Folder Creation

// Create the root Beep folder in a platform-appropriate location:
// Windows: %APPDATA%\TheTechIdea\Beep  (or AppContext.BaseDirectory\TheTechIdea\Beep)
// Linux/macOS: ~/.local/share/TheTechIdea/Beep
string mainFolder = EnvironmentService.CreateMainFolder();

// Create a named application repository sub-folder:
string appFolder = EnvironmentService.CreateAppRepofolder("MyApp");

// Extension form — callable on an IDMEEditor instance:
string path = dmeEditor.CreateMainFolder();

Beep Mapping Setup

// Registers all connection configs, datasource mappings, and query configs for an editor:
dmeEditor.CreateBeepMapping();
EnvironmentService.BeepDataPath and AppRepoDataPath are static read-only properties that cache the last created folder paths. Useful for diagnostics.

ServiceCollectionExtensions

Low-level IServiceCollection extensions for registering individual BeepDM components.

JsonLoader

// Singleton (default for long-lived apps)
services.AddJsonLoader();

// Scoped (per-request in web apps)
services.AddJsonLoaderScoped();

// Transient (new instance each time)
services.AddJsonLoaderTransient();

DMEEditor

// Register as singleton with existing handler + logger instances
services.AddDMEEditor(assemblyHandler, logger);
Prefer AddBeepServices() over these low-level methods. These extensions are intended for scenarios where you need granular control of individual component lifetimes.

ServiceHelper

ServiceHelper is a static service-locator that wraps a cached IServiceProvider. Use it sparingly — prefer constructor injection wherever possible.

// Typically called once in Program.cs / App.xaml.cs after building the host:
ServiceHelper.Initialize(host.Services);

// Resolve a service anywhere, without constructor injection:
var beep = ServiceHelper.GetService<IBeepService>();
var editor = ServiceHelper.GetService<IDMEEditor>();
Do not call GetService before Initialize — it will throw a NullReferenceException. Initialize as early as possible in the application lifecycle.

Lifetime Selection Guide

Application typeRecommended lifetimeRegistration method
WinForms / WPF desktopSingletonAddBeepServices().AsSingleton().Build()
Console / CLISingletonAddBeepServices().AsSingleton().Build()
ASP.NET Core Web API / MVCScopedAddBeepServices().AsScoped().Build()
Blazor ServerScopedAddBeepServices().AsScoped().Build()
Blazor WebAssemblySingletonAddBeepServices().AsSingleton().Build()
Azure Functions (isolated)ScopedAddBeepServices().AsScoped().Build()
Background / Worker servicesSingletonAddBeepServices().AsSingleton().Build()
Never inject a Scoped IBeepService into a Singleton — this creates a captive dependency. If a singleton component needs BeepService, register BeepService as Singleton or use IServiceScopeFactory.

BeepConfigType Values

ValueTypical use
ApplicationFull application with UI, forms, and complete driver set
DataConnectorData-only mode — connections and mappings, no UI components. Used by design-time bootstrap.
ContainerContainer/host scenario
These are the only three values. The enum is declared in DataManagementModelsStandard/Enums/Enums.cs as Application, DataConnector, Container. Earlier revisions of this page listed a Server member, and other pages have listed Plugin and DesignTime — none of those exist.

End-to-End Examples

⚠ Examples 1–4 use the proposed AddBeepFor* API and will not compile. Substitute the real builder, keeping the lifetime each example implies:
// Example 1 (WinForms) and Example 4 (Blazor WASM) -> Singleton
services.AddBeepServices()
    .WithDirectory(AppContext.BaseDirectory).WithAppRepo("MyApp")
    .WithConfigType(BeepConfigType.Application)
    .WithMapping().WithAssemblyLoading()
    .AsSingleton().Build();

// Example 2 (Web API) and Example 3 (Blazor Server) -> Scoped
builder.Services.AddBeepServices()
    .WithDirectory(AppContext.BaseDirectory).WithAppRepo("MyApp")
    .WithConfigType(BeepConfigType.Application)
    .AsScoped().Build();
Example 5 (direct instantiation) and Example 6 (fluent builder) are accurate as written.

Example 1 — WinForms with IHost

// Program.cs
[STAThread]
static void Main()
{
    var host = Host.CreateDefaultBuilder()
        .ConfigureServices((ctx, services) =>
        {
            services.AddBeepForDesktop(opts =>
            {
                opts.DirectoryPath = AppContext.BaseDirectory;
                opts.AppRepoName = "MyDesktopApp";
                opts.EnableProgressReporting = true;
            });
            services.AddSingleton<MainForm>();
        })
        .Build();

    ServiceHelper.Initialize(host.Services);
    var beepService = host.Services.GetRequiredService<IBeepService>();

    Application.Run(host.Services.GetRequiredService<MainForm>());
}

Example 2 — ASP.NET Core Web API

// Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddBeepForWeb(opts =>
{
    opts.DirectoryPath = Path.Combine(builder.Environment.ContentRootPath, "Beep");
    opts.AppRepoName = "MyWebApi";
    opts.EnableConnectionPooling = true;
});

builder.Services.AddControllers();

var app = builder.Build();
app.UseBeepForWeb();
app.MapControllers();
app.Run();

Example 3 — Blazor Server

// Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorComponents().AddInteractiveServerComponents();
builder.Services.AddBeepForBlazorServer(opts =>
{
    opts.AppRepoName = "MyBlazorApp";
    opts.EnableSignalRProgress = true;
    opts.EnableCircuitHandlers = true;
});

var app = builder.Build();
app.MapRazorComponents<App>().AddInteractiveServerRenderMode();
app.Run();

Example 4 — Blazor WebAssembly

// Program.cs
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");

builder.Services.AddBeepForBlazorWasm(opts =>
{
    opts.AppRepoName = "MyBlazorWasmApp";
    opts.UseBrowserStorage = true;
});

await builder.Build().RunAsync();

Example 5 — Direct Instantiation (No DI)

// Useful for unit tests, console scripts, or legacy code
var beep = new BeepService();
beep.Configure(
    directorypath: Path.Combine(Path.GetTempPath(), "BeepTest"),
    containername: "TestContainer",
    configType: BeepConfigType.DataConnector,
    AddasSingleton: false
);

var ds = beep.DMEEditor.GetDataSource("northwind");
ds.Openconnection();

Example 6 — Fluent Builder (Generic / CLI)

var host = Host.CreateDefaultBuilder(args)
    .ConfigureServices((ctx, services) =>
    {
        services.AddBeepServices()
            .WithDirectory(AppContext.BaseDirectory)
            .WithAppRepo("BeepShell")
            .WithConfigType(BeepConfigType.Application)
            .WithAssemblyLoading()
            .WithMapping()
            .AsSingleton()
            .Build();
    })
    .Build();

var beep = host.Services.GetRequiredService<IBeepService>();

Full API Reference — Services Subsystems

BeepService — Complete Public Surface

MemberType/Signature
DMEEditorIDMEEditor {get; set;} — central orchestration
Config_editorIConfigEditor {get; set;}
lgIDMLogger {get; set;}
utilIUtil {get; set;}
ErinfoIErrorsInfo {get; set;}
jsonLoaderIJsonLoader {get; set;}
LLoaderIAssemblyHandler {get; set;}
AppRepoNamestring {get;} — container/repository name
Containername [Obsolete]Alias for AppRepoName
ConfigureationTypeBeepConfigType {get;}
BeepDirectorystring {get;}
AssemblyHandlerTypeAssemblyHandlerType {get; set;}
ServicesIServiceCollection {get;} — concrete class only, not on IBeepService
EnvironmentsDictionary<EnvironmentType, IBeepEnvironment> {get; set;}
Configure(directorypath, containername, configType, AddasSingleton = false)Creates ConfigEditor, Util, assembly handler, DMEEditor, logger, error info; wires the connection catalog repository; optionally registers DI services
ConfigureForDesignTime()Calls Configure(AppContext.BaseDirectory, "DesignTimeContainer", BeepConfigType.DataConnector, true)
LoadConfigurations(appRepoName)Idempotent, lock-guarded; seeds connections, mappings, queries and creates folders
LoadAssemblies()Idempotent, lock-guarded; loads assemblies then restores driver config
LoadAssemblies(Progress<PassedArgs>)Progress-reporting overload
LoadAssembliesAsync(Progress<PassedArgs>)Task — wraps the sync overload in Task.Run
LoadServicesSingleton()Registers the already-constructed component instances as singletons
LoadServicesScoped()Registers component types as keyed scoped services
LoadEnvironments() / SaveEnvironments()Read/write <BeepDirectory>/Environments/*.json
Dispose() / Dispose(bool)Disposes DMEEditor, ConfigEditor, assembly handler; nulls component fields
There is no ReloadConfig() or ReloadAssemblies(). Earlier revisions of this page listed both; neither exists on BeepService or IBeepService. Reloading is not supported — LoadConfigurations() and LoadAssemblies() are guarded by isconfigloaded / isassembliesloaded flags and become no-ops after the first call, so a second call will not re-read anything. To pick up new plugins, construct a new BeepService.

Registration Entry Points — Verified Signatures

All of the following are in DataManagementEngineStandard/Services/RegisterBeepinServiceCollection.cs:

// Fluent builder — returns IBeepServiceBuilder, terminate with .Build()
public static IBeepServiceBuilder AddBeepServices(this IServiceCollection services);

// Options pattern (cross-platform) — returns the built service, not the collection
public static IBeepService AddBeepServices(
    this IServiceCollection services, Action<BeepServiceOptions> configure);

// Positional shorthand (addAsSingleton defaults to true)
public static IBeepService Register(this IServiceCollection services,
    string directoryPath, string containerName,
    BeepConfigType configType, bool addAsSingleton = true);

// Scoped-only registration
public static IServiceCollection RegisterScoped(this IServiceCollection services);

// Mapping helpers
public static IServiceCollection CreateMapping(this IBeepService beepService);
public static Task CreateMappingAsync(this IBeepService beepService, …);

// Lookup / diagnostics
public static string       GetMainFolder();
public static IBeepService GetBeepService(this IDMEEditor dmeEditor);
public static IBeepService GetBeepService(this IServiceProvider serviceProvider);
public static bool         ValidateConfiguration();
public static string       GetConfigurationSummary();
public static void         ResetRegistrationState(bool force = false);

IBeepServiceBuilder — full fluent surface

IBeepServiceBuilder WithDirectory(string directoryPath);
IBeepServiceBuilder WithAppRepo(string appRepoName);
IBeepServiceBuilder WithConfigType(BeepConfigType configType);
IBeepServiceBuilder WithMapping(bool enable = true);
IBeepServiceBuilder WithAssemblyLoading(bool enable = true);
IBeepServiceBuilder WithTimeout(TimeSpan timeout);
IBeepServiceBuilder WithValidation(bool enable = true);
IBeepServiceBuilder WithProperty(string key, object value);
IBeepServiceBuilder WithAssemblyHandler(AssemblyHandlerType handlerType);
IBeepServiceBuilder WithViewDiscovery(bool enable = true);          // default: enabled
IBeepServiceBuilder WithAssembliesToScan(IEnumerable<Assembly> assemblies);
IBeepServiceBuilder AsSingleton();   // desktop
IBeepServiceBuilder AsScoped();      // web / Blazor Server
IBeepServiceBuilder AsTransient();
IBeepService        Build();         // terminal call

Note that view/view-model discovery is on by default — Build() reflects over loaded assemblies for IDM_Addin and IBeepViewModel types unless you call WithViewDiscovery(false). Narrow the scan with WithAssembliesToScan(...) if startup time matters.

Not implemented: AddBeepForDesktop, AddBeepForWeb, AddBeepForBlazorServer, AddBeepForBlazorWasm, AddBeepForMaui, and the DesktopBeepOptions / WebBeepOptions / BlazorBeepOptions classes. The signatures previously shown here were fabricated. Use the fluent builder above and choose the lifetime with AsSingleton() / AsScoped().

BeepServiceOptions — Full Properties

PropertyTypeDefault
AppPathstringrequired
AppRepoNamestringrequired
ConfigTypeBeepConfigTypeDataConnector
AssemblyHandlerTypeAssemblyHandlerTypeDefault
IsDevelopmentboolfalse
AddMappingboolfalse
AddAssemblyLoadingboolfalse
LifetimeServiceLifetime?null (default = Singleton)

Logging Subsystem

5 files: Logging/BeepLog.Core.cs, BeepLog.Levels.cs, BeepLog.Lifetime.cs, BeepLogScopeExtensions.cs, BeepLoggingOptions.cs

public sealed partial class BeepLog : IBeepLog
{
    public bool IsEnabled { get; }                          // from options
    public BeepLogLevel MinLevel { get; }                   // from options

    // Core logging
    public void Log(BeepLogLevel level, string category, string message,
        IReadOnlyDictionary<string,object> properties = null, Exception exception = null);

    // Convenience wrappers (.Levels)
    public void Trace(string category, string message, ...);
    public void Debug(string category, string message, ...);
    public void Info(string category, string message, ...);
    public void Warn(string category, string message, ...);
    public void Error(string category, string message, ...);
    public void Critical(string category, string message, ...);

    // Scope (.Scope)
    public IDisposable BeginScope(string scopeName, IDictionary<string,object> properties = null);

    // Lifetime (.Lifetime)
    public Task FlushAsync(CancellationToken ct = default);
    public void Dispose();
}
PropertyTypeDefault
Enabledboolfalse — must enable explicitly
MinLevelBeepLogLevelInformation
EnableDedupbooltrue — dedup repeated log messages
DedupWindowSecondsint60
EnableRedactionbooltrue — redact PII in messages
EnableSamplingboolfalse
EnableEnrichersbooltrue — attach context at runtime
DupEventIntervalMinutesint5 — synthetic dedup summary

Telemetry Architecture

Core pipeline: Producer (BeepLog / BeepAudit) → Enrichers → Redactors → Samplers → Deduper → Rate Limiter → BoundedChannelQueue → BatchWriter → Sinks

ITelemetrySink

public interface ITelemetrySink : IAsyncDisposable
{
    string Name { get; }
    bool IsHealthy { get; }
    Task WriteBatchAsync(IReadOnlyList<TelemetryEnvelope> batch, CancellationToken ct);
    Task FlushAsync(CancellationToken ct);
}

TelemetryEnvelope

public sealed partial class TelemetryEnvelope
{
    public TelemetryKind Kind { get; set; }                 // Log, Audit, SelfObservability
    public DateTime TimestampUtc { get; set; }
    public string Category { get; set; }
    public BeepLogLevel Level { get; set; }
    public string Message { get; set; }
    public Exception Exception { get; set; }
    public IDictionary<string,object> Properties { get; set; }
    public AuditEvent Audit { get; set; }                    // Non-null only when Kind=Audit
    public string TraceId { get; set; }                      // OpenTelemetry-compatible
    public string CorrelationId { get; set; }
}

IEnricher

public interface IEnricher
{
    string Name { get; }
    void Enrich(TelemetryEnvelope envelope);               // Runs on producer thread, must be cheap
}

All 7 Built-in Enrichers

EnricherAdds
CorrelationEnricherCorrelationId from AsyncLocal / HTTP header
TraceEnricherTraceId + SpanId for OpenTelemetry compat
UserEnricherUserId, UserName, UserEmail from identity
TenantEnricherTenantId from HttpContext.Items
MachineProcessEnricherMachineName, ProcessId, ProcessName, Pid
EnvironmentEnricherEnvironmentName, FrameworkVersion, Platform
ActivityScopeEnricherBeepActivity scope name + parent chain

All Sinks

SinkFileDescription
NullSinkNullSink.csNo-op sink — always healthy, drops all data
MemorySinkMemorySink.csIn-memory ring buffer — used for testing/debugging
FileRollingSinkFileRollingSink.*.cs (3 files)NDJSON rolling files by date — Core, Write, Roll, Health
SqliteSinkSqliteSink.*.cs (6 files)SQLite storage — Core, Write, Query, QueryLog, QueryAudit, PurgeAudit, Schema, Health
CompositeSinkCompositeSink.csFan-out to multiple sinks with per-sink error isolation
RedactingSinkDecoratorRedactingSinkDecorator.csWraps any sink with PII redaction via IRedactor list
BlazorIndexedDbSink3 filesBlazor WASM local storage via IndexedDB (Core, Write, Health)
MauiAppDataSinkMauiAppDataSink.csMAUI app data directory NDJSON sink

Telemetry Pipeline — Key Types

TypeFileRole
TelemetryPipelineTelemetryPipeline.*.cs (3)Orchestrator — queue + stages + drain + flush
BoundedChannelQueueBoundedChannelQueue.csSystem.Threading.Channels bounded queue
BatchWriterBatchWriter.csPeriodic batch writer — drains + fans out to sinks
BackpressureModeBackpressureMode.csenum: Drop, Block, WaitAndDrop
TelemetryKindTelemetryKind.csenum: Log, Audit, SelfObservability
TelemetryFeatureTelemetryFeature.csFeature flag enum (Log, Audit, Diagnostics, etc.)
IRedactorIRedactor.csInterface: Redact(TelemetryEnvelope)
ISamplerISampler.csInterface: ShouldSample(TelemetryEnvelope) → bool
IMessageDeduperIMessageDeduper.csInterface: ShouldDrop(envelope) → bool
WindowedDeduperWindowedDeduper.*.cs (2)Sliding-window dedup with template normalization
MessageTemplateNormalizerMessageTemplateNormalizer.csNormalizes templates for dedup comparison
NdjsonSerializerNdjsonSerializer.csNDJSON serialization for file sinks

Diagnostics

TypeFileDescription
PipelineMetricsPipelineMetrics.*.cs (4)Counters, gauges, snapshots — queue depth, enqueue rate, drain rate, sampled-out count
SinkHealthSinkHealth.csPer-sink health status (IsHealthy, last error, consecutive failures)
SelfEventEmitterSelfEventEmitter.csEmits pipeline self-observability events on health transitions
SelfEventCategorySelfEventCategory.csenum: SinkHealth, QueuePressure, Backpressure, FlushLatency
PeriodicMetricsSnapshotHostedServicePeriodicMetricsSnapshotHostedService.csIHostedService — emits periodic metrics snapshots
PipelineDiagnosticsHooksPipelineDiagnosticsHooks.csDiagnostic hooks for external monitoring

Audit Subsystem

8 files: BeepAudit.Core.cs, BeepAudit.Lifetime.cs, BeepAudit.Query.cs, BeepAuditOptions.cs, NullBeepAudit.cs, Query/IAuditQueryEngine.cs, Query/SqliteAuditQueryEngine.cs, Query/CompositeAuditQueryEngine.cs, Query/FileScanAuditQueryEngine.cs, Query/NdjsonAuditDeserializer.cs

public sealed partial class BeepAudit : IBeepAudit
{
    public bool IsEnabled { get; }
    
    // Record audit events via telemetry pipeline
    public ValueTask RecordValueTaskAsync(AuditEvent auditEvent, CancellationToken ct = default);
    
    // Late-bind Phase 10 compliance services
    public void AttachComplianceServices(
        IAuditQueryEngine queryEngine = null,
        GdprPurgeService purgeService = null,
        IntegrityVerifier integrityVerifier = null);

    // Query (Phase 10) — from .Query partial
    public IAsyncEnumerable<AuditEvent> QueryAsync(AuditQuery query, CancellationToken ct = default);
    public IAsyncEnumerable<AuditEvent> QueryAllAsync(CancellationToken ct = default);
    
    // Purge
    public Task<GdprPurgeResult> PurgeSubjectAsync(string subjectId, CancellationToken ct = default);
    
    // Integrity
    public Task<IntegrityVerificationResult> VerifyIntegrityAsync(CancellationToken ct = default);
    
    // Lifetime (.Lifetime)
    public Task FlushAsync(CancellationToken ct = default);
    public void Dispose();
}

BeepAuditOptions

PropertyTypeDefault
Enabledboolfalse — must enable explicitly
HashChainboolfalse — tamper-evident hashing
EnrichCorrelationIdbooltrue
EnrichUserIdbooltrue
EnrichTenantIdboolfalse
RetentionDaysint0 (indefinite)

Audit Query Engines

EngineBackend
SqliteAuditQueryEngineSQLite — same DB the writer uses
FileScanAuditQueryEngineNDJSON file scan with streaming deserialization
CompositeAuditQueryEngineFederated — queries all registered engines, merges results

Source File Map (90+ files)

CategoryFileContent
Core DIBeepService.csIBeepService impl, 14 props, Configure/Load/Reload
RegisterBeepinServiceCollection.csAddBeepServices, fluent builder, options, validation
ServiceCollectionExtensions.csLow-level JsonLoader/DMEEditor registrations
ServiceHelper.csStatic service-locator helper
Service ExtensionsBeepServiceExtensions.Desktop.csAddBeepLoggingForDesktop, AddBeepAuditForDesktop
BeepServiceExtensions.Web.csAddBeepLoggingForWeb, AddBeepAuditForWeb
BeepServiceExtensions.Blazor.csAddBeepLoggingForBlazor, AddBeepAuditForBlazor
BeepServiceExtensions.Maui.csAddBeepLoggingForMaui, AddBeepAuditForMaui
BeepServiceExtensions.Audit.csAddBeepAudit + AuditPipelineKey
BeepServiceExtensions.Logging.csAddBeepLogging + LoggingPipelineKey
BeepServiceExtensions.Diagnostics.csinternal AttachDiagnostics, RegisterMetricsSnapshot
BeepServiceExtensions.Retention.csAddBeepBudgetEnforcer, AddBeepRetentionSweeper
BeepServiceExtensions.AddinDiscovery.csAddBeepViews, AddBeepViewModels, AddBeepView, AddBeepViewModel
BeepServiceExtensions.DataSources.csAddDataSourceDriver (2 overloads)
BeepServiceExtensions.Schema.csAddBeepSchemaManager
BeepServiceExtensions.EntityDiscovery.csAddBeepEntityDiscovery
LoggingLogging/BeepLog.Core.csFields, ctor, Log entry point
Logging/BeepLog.Levels.csTrace/Debug/Info/Warn/Error/Critical wrappers
Logging/BeepLog.Lifetime.csFlush/Dispose semantics
Logging/BeepLogScopeExtensions.csBeginScope extension methods
Logging/BeepLoggingOptions.csEnabled, MinLevel, EnableDedup, etc.
Telemetry CoreTelemetryPipeline.Core.csQueue + stages + SubmitLog/SubmitAudit entry points
TelemetryPipeline.Drain.csStage application pipeline
TelemetryPipeline.Flush.csGraceful shutdown / FlushAsync
Telemetry AbstractionsITelemetrySink.csSink contract: Name, IsHealthy, WriteBatchAsync, FlushAsync
IEnricher.csEnricher contract: Name, Enrich
IRedactor.csRedactor contract: Redact
ISampler.csSampler contract: ShouldSample
IMessageDeduper.cs (Dedup)Dedup contract: ShouldDrop
TelemetryEnvelope.cs + .Clone.csUnified envelope: Kind, Timestamp, Level, Message, Audit, TraceId, CorrelationId
SinksSinks/NullSink.csNo-op sink
Sinks/MemorySink.csRing buffer for testing
Sinks/FileRollingSink.*.cs (4)NDJSON rolling files w/health
Sinks/SqliteSink.*.cs (7)SQLite w/query, purge, audit, schema, health
Sinks/CompositeSink.csFan-out to multiple sinks
Sinks/RedactingSinkDecorator.csPII redaction wrapper
Sinks/Platform/BlazorIndexedDbSink.*.cs (3)Blazor WASM IDB sink
Sinks/Platform/MauiAppDataSink.csMAUI app data NDJSON sink
Context EnrichersContext/CorrelationEnricher.csCorrelationId from AsyncLocal/HTTP header
Context/TraceEnricher.csTraceId + SpanId for OpenTelemetry
Context/UserEnricher.csUserId, UserName, UserEmail
Context/TenantEnricher.csTenantId from HttpContext
Context/MachineProcessEnricher.csMachineName, ProcessId
Context/EnvironmentEnricher.csEnvironmentName, FrameworkVersion
Context/ActivityScopeEnricher.csBeepActivity scope chain
DiagnosticsDiagnostics/PipelineMetrics.*.cs (4)Counters, gauges, snapshots
Diagnostics/SinkHealth.csPer-sink health tracking
Diagnostics/SelfEventEmitter.csPipeline self-observability events
Diagnostics/SelfEventCategory.csSinkHealth, QueuePressure, etc.
Diagnostics/PeriodicMetricsSnapshotHostedService.csIHostedService periodic snapshots
Diagnostics/PipelineDiagnosticsHooks.csExternal monitoring hooks
DedupDedup/WindowedDeduper.Core.csSliding-window dedup logic
Dedup/WindowedDeduper.Window.csWindow management
Dedup/IMessageDeduper.csDedup contract
Dedup/MessageTemplateNormalizer.csTemplate normalization
AuditAudit/BeepAudit.Core.csRecordValueTaskAsync, hash-chain signing
Audit/BeepAudit.Lifetime.csFlush/Dispose
Audit/BeepAudit.Query.csQueryAllAsync, PurgeSubjectAsync
Audit/BeepAuditOptions.csEnabled, HashChain, enrichment flags
Audit/NullBeepAudit.csNo-op disabled audit
Audit EnginesAudit/Query/IAuditQueryEngine.csQuery contract
Audit/Query/SqliteAuditQueryEngine.csSQLite-backed query
Audit/Query/CompositeAuditQueryEngine.csFederated multi-engine query
Audit/Query/FileScanAuditQueryEngine.csNDJSON file scanning
OtherEnvironmentService.csPlatform folder creation, path mapping
Telemetry/BoundedChannelQueue.csChannel-based bounded queue
Telemetry/BatchWriter.csPeriodic batch flush to sinks
Telemetry/NdjsonSerializer.csNDJSON serialization
Telemetry/PlatformPaths.csPlatform path resolution
ExamplesExamples/WebApiExample.csMinimal ASP.NET Core registration
Examples/BlazorServerExample.csBlazor Server registration
Examples/DesktopMinimalExample.csDesktop app minimal setup
Examples/LoggingWebApiExample.csWeb API logging configuration
Examples/LoggingBlazorExample.csBlazor logging configuration
Examples/LoggingDesktopExample.csDesktop logging configuration
Examples/AuditDistributedExample.csDistributed audit setup
Examples/AuditFormsExample.csForms-based audit recording