Wiaoj.DistributedCounter.Abstractions
0.1.0-alpha.3
See the version list below for details.
dotnet add package Wiaoj.DistributedCounter.Abstractions --version 0.1.0-alpha.3
NuGet\Install-Package Wiaoj.DistributedCounter.Abstractions -Version 0.1.0-alpha.3
<PackageReference Include="Wiaoj.DistributedCounter.Abstractions" Version="0.1.0-alpha.3" />
<PackageVersion Include="Wiaoj.DistributedCounter.Abstractions" Version="0.1.0-alpha.3" />
<PackageReference Include="Wiaoj.DistributedCounter.Abstractions" />
paket add Wiaoj.DistributedCounter.Abstractions --version 0.1.0-alpha.3
#r "nuget: Wiaoj.DistributedCounter.Abstractions, 0.1.0-alpha.3"
#:package Wiaoj.DistributedCounter.Abstractions@0.1.0-alpha.3
#addin nuget:?package=Wiaoj.DistributedCounter.Abstractions&version=0.1.0-alpha.3&prerelease
#tool nuget:?package=Wiaoj.DistributedCounter.Abstractions&version=0.1.0-alpha.3&prerelease
Wiaoj.DistributedCounter.Abstractions
Core contracts, interfaces, and value primitives for the Wiaoj.DistributedCounter library.
This package defines the public API surface, storage provider interfaces, and domain value objects required to consume or extend the distributed counter system without referencing concrete storage implementations or runtime hosting packages.
Installation
dotnet add package Wiaoj.DistributedCounter.Abstractions
Domain Primitives and Types
CounterKey (readonly record struct)
- Validated key type ensuring consistent string representation across storage providers.
- Implements
ISpanParsable<CounterKey>,IUtf8SpanParsable<CounterKey>, andISpanFormattableto support span-based parsing and formatting without unnecessary allocations. - Includes a dedicated
JsonConverter(CounterKeyJsonConverter) for direct JSON property/value serialization.
CounterValue (readonly record struct)
- Numerical wrapper around a
longvalue. - Implements generic math interfaces (
IComparisonOperators,IAdditionOperators,ISubtractionOperators). - Enforces
checkedarithmetic operators (+,-), throwingOverflowExceptionon boundary overflows rather than wrapping silently. - Explicit cast to
longprevents unintentional type coercion; implicit conversion fromlongis supported.
CounterExpiry (readonly record struct)
- Encapsulates expiration policies and sliding TTL windows.
- Supports
CounterExpiry.Infinite(nullduration) for persistent counters. - Provides factory methods (
From,FromSeconds,FromMinutes,FromTicks) with non-positive duration validation.
CounterLimitResult (readonly record struct)
Returned by quota-evaluating operations (TryIncrementAsync, TryDecrementAsync):
IsAllowed(bool): Whether the requested amount was within limit boundaries.CurrentValue(long): Current counter value after the operation (or unchanged value if rejected).Remaining(long): Remaining capacity until reaching the limit threshold.Ttl(TimeSpan?): Live remaining time-to-live of the sliding expiration window, if available from storage.
CounterValueCollection (readonly struct)
- Read-only batch container returned by
IDistributedCounterService.GetValuesAsync. - Uses a reference-counted
DisposeGuardto return rentedDictionary<string, CounterValue>buffers to the underlying object pool upon disposal. - Safe after disposal: indexers and
TryGetValuereturnCounterValue.Zerowithout throwing exceptions.
CounterStrategy (enum)
Immediate: Every operation is dispatched synchronously to storage.Buffered: Operations are accumulated in local memory and flushed in batches by background workers.
Core Interfaces
| Interface | Role |
|---|---|
IDistributedCounter |
Core operations: IncrementAsync, DecrementAsync, TryIncrementAsync, TryDecrementAsync, GetValueAsync, SetAsync, and ResetAsync. |
IDistributedCounter<TTag> |
Open-generic DI contract providing tag-level categorization and scoped key resolution via .ForKey(key). |
ICounterStorage |
Low-level storage provider contract implemented by storage backends (e.g. In-Memory, Redis). |
IDistributedCounterFactory |
Engine factory contract for creating and caching counter instances by name or tag. |
IDistributedCounterService |
System-level batch queries (GetValuesAsync), manual flush triggers (FlushAllAsync), and state resets (ResetAllAsync). |
ICounterKeyBuilder |
Contract for formatting names, tags, and dynamic keys into structured CounterKey strings. |
Configuration Models
DistributedCounterOptions: Root configuration model holding global prefixes (GlobalKeyPrefix), default strategy (DefaultStrategy), auto-flush intervals (AutoFlushInterval), and tag registrations.CounterConfiguration: Specific settings for a named counter or tag. Allows configuring dedicated strategies, storage types (UseStorage<T>()), keyed storage identifiers (UseKeyedStorage(key)), or factory delegates (UseStorage(factory)).
Usage Examples
Consuming IDistributedCounter<TTag> in a Service
using Wiaoj.DistributedCounter;
public sealed class RateLimiterService(IDistributedCounter<RateLimitTag> rateLimiter) {
public async Task<bool> CheckRequestAllowedAsync(string clientIp, CancellationToken cancellationToken) {
CounterLimitResult result = await rateLimiter
.ForKey(clientIp)
.TryIncrementAsync(
amount: 1,
limit: 10,
expiry: CounterExpiry.FromMinutes(1),
cancellationToken: cancellationToken);
return result.IsAllowed;
}
}
public sealed class RateLimitTag;
Implementing a Custom Storage Backend
using Wiaoj.DistributedCounter;
public sealed class CustomStorage : ICounterStorage {
public ValueTask<CounterValue> AtomicIncrementAsync(
CounterKey key,
long amount,
CounterExpiry expiry,
CancellationToken cancellationToken) {
// Storage-specific atomic increment implementation
return new ValueTask<CounterValue>(new CounterValue(amount));
}
public ValueTask<CounterLimitResult> TryIncrementAsync(
CounterKey key,
long amount,
long limit,
CounterExpiry expiry,
CancellationToken cancellationToken) {
// Storage-specific limit evaluation implementation
return new ValueTask<CounterLimitResult>(new CounterLimitResult(true, amount, limit - amount, null));
}
public ValueTask<CounterLimitResult> TryDecrementAsync(CounterKey key, long amount, long minLimit, CounterExpiry expiry, CancellationToken cancellationToken) => throw new NotImplementedException();
public ValueTask<CounterValue> GetAsync(CounterKey key, CancellationToken cancellationToken) => throw new NotImplementedException();
public ValueTask<TimeSpan?> GetTtlAsync(CounterKey key, CancellationToken cancellationToken) => throw new NotImplementedException();
public ValueTask<IDictionary<CounterKey, CounterValue>> GetManyAsync(IEnumerable<CounterKey> keys, CancellationToken cancellationToken) => throw new NotImplementedException();
public ValueTask GetManyAsync(ReadOnlyMemory<CounterKey> keys, Memory<CounterValue> destination, CancellationToken cancellationToken) => throw new NotImplementedException();
public ValueTask DeleteAsync(CounterKey key, CancellationToken cancellationToken) => throw new NotImplementedException();
public ValueTask SetAsync(CounterKey key, CounterValue value, CounterExpiry expiry, CancellationToken cancellationToken) => throw new NotImplementedException();
public ValueTask BatchIncrementAsync(ReadOnlyMemory<CounterUpdate> updates, Memory<long> resultDestination, CancellationToken cancellationToken) => throw new NotImplementedException();
}
License
This project is licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- Wiaoj.Abstractions (>= 0.1.0-alpha.3)
- Wiaoj.Preconditions (>= 0.1.0-alpha.3)
- Wiaoj.Primitives (>= 0.1.0-alpha.3)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on Wiaoj.DistributedCounter.Abstractions:
| Package | Downloads |
|---|---|
|
Wiaoj.DistributedCounter
Package Description |
|
|
Wiaoj.DistributedCounter.Redis
Package Description |
|
|
Wiaoj.RateLimiting
Package Description |
|
|
Wiaoj.Resilience
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-alpha.7 | 39 | 9/18/2026 |
| 0.1.0-alpha.6 | 51 | 9/16/2026 |
| 0.1.0-alpha.5 | 49 | 9/16/2026 |
| 0.1.0-alpha.4 | 54 | 9/16/2026 |
| 0.1.0-alpha.3 | 56 | 9/15/2026 |
| 0.1.0-alpha.2 | 98 | 9/15/2026 |
| 0.1.0-alpha.1 | 66 | 9/14/2026 |
| 0.0.1-alpha.112-preview | 73 | 9/13/2026 |
| 0.0.1-alpha.111-preview | 65 | 9/13/2026 |
| 0.0.1-alpha.110-preview | 76 | 9/12/2026 |
| 0.0.1-alpha.109-preview | 78 | 9/11/2026 |
| 0.0.1-alpha.108-preview | 90 | 9/8/2026 |
| 0.0.1-alpha.107-preview | 99 | 9/8/2026 |
| 0.0.1-alpha.106-preview | 87 | 9/8/2026 |
| 0.0.1-alpha.105-preview | 85 | 9/8/2026 |
| 0.0.1-alpha.104-preview | 89 | 9/7/2026 |
| 0.0.1-alpha.103-preview | 84 | 9/7/2026 |
| 0.0.1-alpha.102-preview | 87 | 9/6/2026 |
| 0.0.1-alpha.101-preview | 113 | 9/6/2026 |
| 0.0.1-alpha.100-preview | 86 | 9/6/2026 |