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

MemberTypeDescription
BeepServiceIBeepService (get)The acquired Beep service instance
ContextKeystring (get)Unique context key for this lease
Dispose()voidCalls the manager's Release() to decrement ref count. Disposes the service if ref count reaches 0.

Acquire Methods

MethodPurpose
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