DistributedLeasing.Abstractions
5.1.0
dotnet add package DistributedLeasing.Abstractions --version 5.1.0
NuGet\Install-Package DistributedLeasing.Abstractions -Version 5.1.0
<PackageReference Include="DistributedLeasing.Abstractions" Version="5.1.0" />
<PackageVersion Include="DistributedLeasing.Abstractions" Version="5.1.0" />
<PackageReference Include="DistributedLeasing.Abstractions" />
paket add DistributedLeasing.Abstractions --version 5.1.0
#r "nuget: DistributedLeasing.Abstractions, 5.1.0"
#:package DistributedLeasing.Abstractions@5.1.0
#addin nuget:?package=DistributedLeasing.Abstractions&version=5.1.0
#tool nuget:?package=DistributedLeasing.Abstractions&version=5.1.0
DistributedLeasing.Abstractions
The foundation package for building distributed leasing systems in .NET
This package provides the core framework for distributed leasing with comprehensive authentication, observability, and extensibility support. It includes contracts, base implementations, Azure authentication, configuration, event system, exceptions, and observability components.
When to Use This Package
Use this package directly when:
- Building a custom lease provider for a different backend (e.g., PostgreSQL, MongoDB, etcd)
- Extending the framework with custom authentication mechanisms
- Integrating advanced observability features into your application
Use a provider package instead when:
- You need Azure Blob Storage leasing → DistributedLeasing.Azure.Blob
- You need Azure Cosmos DB leasing → DistributedLeasing.Azure.Cosmos
- You need Azure Redis leasing → DistributedLeasing.Azure.Redis
Provider packages automatically include this package as a dependency - you don't need to install it separately.
What's Included
Core Contracts
ILeaseProvider - Factory for creating lease managers
public interface ILeaseProvider
{
Task<ILeaseManager> CreateLeaseManagerAsync(string leaseKey);
}
ILeaseManager - Manages lease acquisition and release
public interface ILeaseManager
{
Task<ILease?> AcquireAsync(TimeSpan? duration = null);
Task<ILease?> TryAcquireAsync(TimeSpan? duration = null);
}
ILease - Represents an active lease with auto-renewal
public interface ILease : IAsyncDisposable
{
string LeaseId { get; }
bool IsActive { get; }
Task ReleaseAsync();
event EventHandler<LeaseRenewedEventArgs>? LeaseRenewed;
event EventHandler<LeaseLostEventArgs>? LeaseLost;
}
Base Implementations
- LeaseBase - Abstract base class for implementing lease instances
- LeaseManagerBase - Abstract base class for implementing lease managers
- Handles automatic renewal, event dispatching, and lifecycle management
Azure Authentication
Comprehensive Azure authentication support with multiple modes:
Supported Authentication Modes:
- Auto - Automatic credential chain (recommended for most scenarios)
- ManagedIdentity - System-assigned or user-assigned managed identity
- WorkloadIdentity - Kubernetes workload identity or GitHub OIDC
- ServicePrincipal - Certificate-based or client secret authentication
- FederatedCredential - External OIDC token exchange
- Development - Azure CLI, Visual Studio, VS Code (dev-only)
See the Authentication Configuration section below for detailed setup.
Configuration
LeaseOptions - Centralized lease configuration
- Lease duration settings
- Auto-renewal intervals
- Retry policies
- Custom metadata
Event System
Lifecycle Events:
LeaseRenewed- Fired when a lease is successfully renewedLeaseLost- Fired when a lease is lost (expiration, exception)LeaseRenewalFailed- Fired when renewal fails but lease still active
Event Args:
LeaseRenewedEventArgs- Contains new expiration timeLeaseLostEventArgs- Contains reason and exception detailsLeaseRenewalFailedEventArgs- Contains exception and retry information
Exceptions
LeaseException - Base exception for all lease-related errors
LeaseAcquisitionException- Failed to acquire leaseLeaseRenewalException- Failed to renew leaseLeaseReleaseException- Failed to release lease
Observability
Health Checks:
services.AddHealthChecks()
.AddCheck<LeaseHealthCheck>("lease-health");
Metrics (OpenTelemetry):
leasing.acquire.duration- Lease acquisition timeleasing.acquire.success- Successful acquisitions counterleasing.acquire.failure- Failed acquisitions counterleasing.renewal.success- Successful renewals counterleasing.renewal.failure- Failed renewals counterleasing.active.count- Active leases gauge
Distributed Tracing (OpenTelemetry):
- Activity source:
DistributedLeasing - Spans for acquire, renew, release operations
- Automatic correlation with parent activities
Installation
dotnet add package DistributedLeasing.Abstractions
Note: You typically don't install this package directly. Install a provider package instead, which will include this automatically.
Authentication Configuration
All Azure providers support unified authentication through configuration. No code changes required to switch authentication modes.
Configuration Structure
{
"Authentication": {
"Mode": "Auto"
}
}
Mode 1: Auto (Recommended)
Automatically tries credentials in order: Environment → Managed Identity → Workload Identity → Development tools.
{
"Authentication": {
"Mode": "Auto"
}
}
Best for: Production and development environments with minimal configuration.
Mode 2: Managed Identity
System-Assigned Managed Identity:
{
"Authentication": {
"Mode": "ManagedIdentity"
}
}
User-Assigned Managed Identity:
{
"Authentication": {
"Mode": "ManagedIdentity",
"ManagedIdentity": {
"ClientId": "12345678-1234-1234-1234-123456789012"
}
}
}
Best for: Azure VMs, App Services, Container Apps, AKS with managed identity.
Mode 3: Workload Identity
For Kubernetes or GitHub Actions with OIDC:
{
"Authentication": {
"Mode": "WorkloadIdentity"
}
}
Best for: AKS with workload identity, GitHub Actions with OIDC federation.
Requires environment variables:
AZURE_TENANT_IDAZURE_CLIENT_IDAZURE_FEDERATED_TOKEN_FILE
Mode 4: Service Principal
Certificate-Based (Recommended):
{
"Authentication": {
"Mode": "ServicePrincipal",
"ServicePrincipal": {
"TenantId": "87654321-4321-4321-4321-210987654321",
"ClientId": "abcdef12-abcd-abcd-abcd-abcdef123456",
"CertificatePath": "/path/to/certificate.pfx"
}
}
}
Client Secret (Not Recommended for Production):
{
"Authentication": {
"Mode": "ServicePrincipal",
"ServicePrincipal": {
"TenantId": "87654321-4321-4321-4321-210987654321",
"ClientId": "abcdef12-abcd-abcd-abcd-abcdef123456",
"ClientSecret": "your-client-secret"
}
}
}
Best for: CI/CD pipelines, non-Azure environments.
Mode 5: Development
Uses local development tools (Azure CLI, Visual Studio, VS Code):
{
"Authentication": {
"Mode": "Development"
}
}
Best for: Local development only. Automatically blocked in Production/Staging environments.
Requires: az login or signed in to Visual Studio/VS Code.
Event System Usage
Monitoring Lease Lifecycle
var lease = await leaseManager.AcquireAsync();
lease.LeaseRenewed += (sender, e) =>
{
Console.WriteLine($"Lease renewed. New expiration: {e.NewExpiration}");
};
lease.LeaseLost += (sender, e) =>
{
Console.WriteLine($"Lease lost! Reason: {e.Reason}");
if (e.Exception != null)
{
Console.WriteLine($"Exception: {e.Exception.Message}");
}
};
lease.LeaseRenewalFailed += (sender, e) =>
{
Console.WriteLine($"Renewal failed but lease still active: {e.Exception.Message}");
};
Graceful Shutdown on Lease Loss
var cancellationTokenSource = new CancellationTokenSource();
lease.LeaseLost += (sender, e) =>
{
Console.WriteLine("Lease lost - initiating graceful shutdown");
cancellationTokenSource.Cancel();
};
try
{
await ProcessWorkAsync(cancellationTokenSource.Token);
}
finally
{
await lease.ReleaseAsync();
}
Observability Integration
Health Checks
Register the lease health check to monitor lease system health:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
services.AddHealthChecks()
.AddCheck<LeaseHealthCheck>(
"lease-health",
failureStatus: HealthStatus.Degraded,
tags: new[] { "leasing", "distributed" });
Access health status:
curl http://localhost:5000/health
Metrics with OpenTelemetry
Configure OpenTelemetry to collect lease metrics:
using OpenTelemetry.Metrics;
using DistributedLeasing.Abstractions.Observability;
services.AddOpenTelemetry()
.WithMetrics(builder =>
{
builder.AddMeter(LeasingMetrics.MeterName);
});
Available Metrics:
leasing.acquire.duration(Histogram) - Time to acquire leaseleasing.acquire.success(Counter) - Successful acquisitionsleasing.acquire.failure(Counter) - Failed acquisitionsleasing.renewal.success(Counter) - Successful renewalsleasing.renewal.failure(Counter) - Failed renewalsleasing.active.count(Gauge) - Currently active leases
Distributed Tracing
Enable distributed tracing with OpenTelemetry:
using OpenTelemetry.Trace;
using DistributedLeasing.Abstractions.Observability;
services.AddOpenTelemetry()
.WithTracing(builder =>
{
builder.AddSource(LeasingActivitySource.SourceName);
});
Traced Operations:
lease.acquire- Lease acquisitionlease.renew- Lease renewallease.release- Lease release
Each span includes tags: lease.key, lease.id, lease.duration
Building Custom Providers
Extend the framework to support additional backends:
1. Implement ILease
using DistributedLeasing.Abstractions.Core;
public class CustomLease : LeaseBase
{
public CustomLease(
string leaseId,
string leaseKey,
TimeSpan leaseDuration,
ILogger logger)
: base(leaseId, leaseKey, leaseDuration, logger)
{
}
protected override async Task<bool> RenewLeaseAsync(CancellationToken cancellationToken)
{
// Implement backend-specific renewal logic
return await YourBackend.RenewAsync(LeaseId, cancellationToken);
}
protected override async Task ReleaseLeaseInternalAsync(CancellationToken cancellationToken)
{
// Implement backend-specific release logic
await YourBackend.ReleaseAsync(LeaseId, cancellationToken);
}
}
2. Implement ILeaseManager
using DistributedLeasing.Abstractions.Core;
public class CustomLeaseManager : LeaseManagerBase
{
public CustomLeaseManager(
string leaseKey,
LeaseOptions options,
ILogger logger)
: base(leaseKey, options, logger)
{
}
protected override async Task<ILease?> AcquireLeaseInternalAsync(
TimeSpan leaseDuration,
CancellationToken cancellationToken)
{
// Implement backend-specific acquisition logic
var leaseId = await YourBackend.TryAcquireAsync(LeaseKey, leaseDuration);
if (leaseId == null)
return null;
return new CustomLease(leaseId, LeaseKey, leaseDuration, Logger);
}
}
3. Implement ILeaseProvider
using DistributedLeasing.Abstractions.Contracts;
public class CustomLeaseProvider : ILeaseProvider
{
private readonly CustomLeaseProviderOptions _options;
private readonly ILogger<CustomLeaseProvider> _logger;
public CustomLeaseProvider(
CustomLeaseProviderOptions options,
ILogger<CustomLeaseProvider> logger)
{
_options = options;
_logger = logger;
}
public async Task<ILeaseManager> CreateLeaseManagerAsync(string leaseKey)
{
// Validate and create manager
return new CustomLeaseManager(leaseKey, _options.LeaseOptions, _logger);
}
}
Framework Compatibility
- .NET Standard 2.0 - Compatible with .NET Framework 4.6.1+, .NET Core 2.0+
- .NET 8.0 - Long-term support release
- .NET 10.0 - Latest release
Package Dependencies
- Azure.Core - Azure SDK core functionality
- Azure.Identity - Azure authentication
- Microsoft.Extensions.* - Configuration, DI, logging, health checks
- Microsoft.SourceLink.GitHub - Source debugging support
Related Packages
- DistributedLeasing.Azure.Blob - Azure Blob Storage provider
- DistributedLeasing.Azure.Cosmos - Azure Cosmos DB provider
- DistributedLeasing.Azure.Redis - Azure Redis provider
- DistributedLeasing.ChaosEngineering - Testing utilities
Samples and Documentation
- BlobLeaseSample - Comprehensive Azure Blob leasing examples
- CosmosLeaseSample - Azure Cosmos DB leasing examples
- GitHub Repository
License
MIT License - see LICENSE for details.
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Azure.Core (>= 1.50.0)
- Azure.Identity (>= 1.17.1)
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Options (>= 10.0.1)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.1)
-
net10.0
- Azure.Core (>= 1.50.0)
- Azure.Identity (>= 1.17.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Options (>= 10.0.1)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.1)
-
net8.0
- Azure.Core (>= 1.50.0)
- Azure.Identity (>= 1.17.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.1)
- Microsoft.Extensions.Options (>= 10.0.1)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.1)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on DistributedLeasing.Abstractions:
| Package | Downloads |
|---|---|
|
DistributedLeasing.Azure.Blob
Azure Blob Storage provider for the DistributedLeasing library. Implements distributed leasing using native Azure Blob lease capabilities with managed identity support. |
|
|
DistributedLeasing.Azure.Redis
Azure Managed Redis provider for the DistributedLeasing library. Implements distributed leasing using Redlock algorithm with managed identity support. |
|
|
DistributedLeasing.Azure.Cosmos
Azure Cosmos DB provider for the DistributedLeasing library. Implements distributed leasing using optimistic concurrency with ETag and managed identity support. |
|
|
DistributedLeasing.ChaosEngineering
Chaos engineering support for DistributedLeasing library. Inject controlled failures to test resilience. FOR TESTING ONLY - NOT FOR PRODUCTION. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Minor version 5.1: Added Redis distributed locking sample with comprehensive documentation, enhanced setup-resources.sh script with --project argument supporting blob/cosmos/redis selection, interactive configuration wizard for all samples. Includes RedisLeaseSample demonstrating atomic SET NX operations, lock competition, and metadata inspection. No breaking API changes - safe to upgrade from 5.0.x.