DesignTimeBeepServiceManager
Reference-counted, thread-safe leasing mechanism for IBeepService instances at design time -- prevents repeated expensive initialization of BeepService contexts
Table of Contents
Overview
Namespace: TheTechIdea.Beep.Winform.Controls.Design.Server.Helpers
Visibility: internal static
A reference-counted, thread-safe leasing mechanism for IBeepService instances used at design time. Prevents repeated expensive initialization of BeepService contexts (which may involve configuration loading, logging adapter setup, and resource allocation) by caching them per unique context key and sharing them across multiple design-time consumers. Leases are disposable: when the last lease is released, the service context is cleaned up.
Uses a static SyncRoot lock object and a ConcurrentDictionary<string, ContextEntry> for the context cache.
Lease Model
IDesignTimeServiceLease (internal interface, extends IDisposable):
| Member | Type | Description |
|---|---|---|
| BeepService | IBeepService (get) | The acquired Beep service instance |
| ContextKey | string (get) | Unique context key for this lease |
| Dispose() | void | Calls the manager's Release() to decrement ref count. Disposes the service if ref count reaches 0. |
Acquire Methods
| Method | Purpose |
|---|---|
| Acquire(BeepDataConnection) | Builds context key from component (PersistenceScope, AppRepoName, ActiveProfileName, DirectoryPath). Creates/reuses cached IBeepService. Returns lease. |
| AcquireForBlockDesigner(string?, string) | For block designer usage. Resolves base directory (falls back to AppContext.BaseDirectory). Builds key as "BlockDesigner|{appRepoName}|{baseDirectory}". Returns lease. |
Internal Architecture
Key private members:
- Release(contextKey) -- Thread-safe: decrements ref count; when it reaches 0, removes context entry and disposes the IBeepService if it implements IDisposable
- BuildContextKey(component) -- Creates a "PersistenceScope|Profile|AppRepoName|BaseDirectory" key
- AcquireInternal(contextKey, createService) -- Thread-safe factory: looks up or creates ContextEntry via the factory Func, increments ref count, returns a new DesignTimeServiceLease
- CreateServiceContext(...) -- Creates a new BeepService() and calls service.Configure(baseDirectory, appRepoName, BeepConfigType.DataConnector, true). Wraps in try/catch to suppress exceptions from missing runtime dependencies (e.g., logging adapters).
- ContextEntry class -- Private sealed nested. Holds BeepService, RefCount (int), LastAccessUtc (DateTime).
Examples
// Used by BeepDataConnection at design time:
using (var lease = DesignTimeBeepServiceManager.Acquire(this))
{
var service = lease.BeepService;
// Use service to test connections, load schemas, etc.
// Lease is auto-released when disposed
}
// Used by block designers:
using (var lease = DesignTimeBeepServiceManager
.AcquireForBlockDesigner(baseDir, "MyApp"))
{
var service = lease.BeepService;
// Use service to populate EntityStructure metadata
}
// When all leases released, IBeepService is disposed