# Snowflake.IdGen **Repository Path**: ymjake/nsnowflake-id ## Basic Information - **Project Name**: Snowflake.IdGen - **Description**: Snowflake.IdGen - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-05-16 - **Last Updated**: 2026-05-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # YMJake.Snowflake.IdGen A lightweight, zero-dependency Snowflake ID library for .NET. --- ## Installation ```bash dotnet add package YMJake.Snowflake.IdGen dotnet add package YMJake.Snowflake.IdGen.AspNetCore ``` --- ## Quick Start ```csharp SnowflakeId.Configure(3); var id = SnowflakeId.New(); Console.WriteLine(id); // 313860533411381248 Console.WriteLine(id.WorkerId); // 3 Console.WriteLine(id.Sequence); // 0 Console.WriteLine(id.CreatedAt); // 2026-05-16T02:09:42+00:00 ``` --- ## ASP.NET Core ```csharp builder.Services.AddSnowflakeId(3); ``` --- ## Distributed Coordination The library does not include a built-in distributed coordinator. `WorkerId` assignment is a deployment concern, not an ID generation concern. For dynamic multi-instance deployments, implement `WorkerIdProviderBase`: ```csharp public sealed class RedisWorkerIdProvider(IConnectionMultiplexer redis) : WorkerIdProviderBase { private readonly IDatabase _db = redis.GetDatabase(); private ushort _workerId; private readonly string _identity = $"{Environment.MachineName}-{Guid.NewGuid()}"; public override ushort GetWorkerId() => _workerId; protected override async Task AcquireWorkerIdAsync( CancellationToken cancellationToken) { for (ushort i = 0; i < 1024; i++) { var ok = await _db.StringSetAsync( $"snowflake:workerid:{i}", _identity, TimeSpan.FromSeconds(30), When.NotExists); if (ok) { _workerId = i; return i; } } throw new InvalidOperationException("No available workerId."); } protected override async Task RefreshAsync( CancellationToken cancellationToken) { await _db.KeyExpireAsync( $"snowflake:workerid:{_workerId}", TimeSpan.FromSeconds(30)); } protected override async Task ReleaseAsync( CancellationToken cancellationToken) { await _db.KeyDeleteAsync($"snowflake:workerid:{_workerId}"); } } ``` Register: ```csharp builder.Services.AddSnowflakeId(); ``` Full samples for Redis / Etcd / Consul / ZooKeeper are available in the `demo/` directory. --- ## EF Core `SnowflakeId` is a `readonly struct`. Register a `ValueConverter` to use it as a primary key: ```csharp public class SnowflakeIdValueConverter() : ValueConverter( v => v.ToLong(), v => SnowflakeId.FromLong(v)); // Apply globally in DbContext protected override void ConfigureConventions(ModelConfigurationBuilder config) { config.Properties() .HaveConversion(); } ``` Auto-generate IDs on insert: ```csharp public class Order { public SnowflakeId Id { get; set; } = SnowflakeId.New(); } ``` --- ## Design ``` YMJake.Snowflake.IdGen → ID generation only, zero dependencies YMJake.Snowflake.IdGen.AspNetCore → DI integration, WorkerIdProviderBase demo/ → Redis / Etcd / Consul / ZooKeeper coordination examples ``` The library boundary stops at ID generation. Distributed coordination complexity belongs to the caller. --- ## Snowflake Layout ``` [1 bit sign] [41 bit timestamp] [10 bit workerId] [12 bit sequence] ``` Epoch: `2024-01-01 UTC` Max workerId: `1023` Max sequence: `4095` Capacity: `4096 IDs/ms per instance` --- ## License MIT