Sfid.EntityFramework
1.0.1
dotnet add package Sfid.EntityFramework --version 1.0.1
NuGet\Install-Package Sfid.EntityFramework -Version 1.0.1
<PackageReference Include="Sfid.EntityFramework" Version="1.0.1" />
<PackageVersion Include="Sfid.EntityFramework" Version="1.0.1" />
<PackageReference Include="Sfid.EntityFramework" />
paket add Sfid.EntityFramework --version 1.0.1
#r "nuget: Sfid.EntityFramework, 1.0.1"
#:package Sfid.EntityFramework@1.0.1
#addin nuget:?package=Sfid.EntityFramework&version=1.0.1
#tool nuget:?package=Sfid.EntityFramework&version=1.0.1
<p align="center"> <img src="assets/logo/sfid-logo-source.svg" alt="Sfid.Net logo" width="360" /> </p>
Sfid.Net
Sfid.Net is a .NET library for generating Twitter Snowflake-compatible 64-bit distributed identifiers. It supports raw long IDs, strongly typed IDs, process-wide runtime helpers, host-based bootstrapping, and optional Entity Framework Core integration.
Packages
Sfid.Net: core generator, parser, runtime, typed ID abstractions, and dependency injection helpers exposed through theSfidNetnamespace.Sfid.EntityFramework: EF Core converters, comparers, key configuration helpers, and generate-on-save support.
Installation
dotnet add package Sfid.Net
dotnet add package Sfid.EntityFramework
Install Sfid.EntityFramework only when you need EF Core mapping helpers.
The packages currently target net8.0, net9.0, and net10.0.
Install the Sfid.Net package, then import the public API with using SfidNet;.
Quick Start
using SfidNet;
var generator = new SfidGenerator(
new SfidOptions
{
DatacenterId = 1,
WorkerId = 7,
ClockRegressionTolerance = TimeSpan.FromMilliseconds(2),
});
long rawId = generator.NextId();
Sfid typedSfid = generator.Next<Sfid>();
You can also define strongly typed identifiers:
using SfidNet.Abstractions;
public readonly record struct OrderId(long Value) : ISfid<OrderId>
{
public static OrderId FromInt64(long value) => new(value);
}
OrderId orderId = generator.Next<OrderId>();
Dependency Injection
The library can bootstrap a process-wide runtime generator from configuration and host metadata:
builder.Services.AddSnowfake(builder.Configuration, builder.Environment);
You can also configure it directly in code:
builder.Services.AddSnowfake(options =>
{
options.DatacenterId = 1;
options.WorkerId = 7;
options.WorkerCapacity = 32;
});
The configuration section name is currently Snowfake, and the host bootstrapper can derive node identity from application and instance metadata when explicit IDs are not supplied.
For a full configuration matrix with appsettings.json, environment variables, fallback rules, and production deployment patterns, see the appsettings configuration guide.
Parsing and Runtime Helpers
using SfidNet;
var parsed = SfidParser.Parse<OrderId>("123456789012345678");
var fromLong = SfidParser.FromInt64<Sfid>(123456789012345678);
SfidRuntime.Bootstrap(new SfidOptions
{
DatacenterId = 2,
WorkerId = 9,
});
Sfid generated = Sfid.Generate();
JSON for APIs
Sfid works out of the box in JSON request and response bodies because the type carries its own System.Text.Json converter. If you also expose custom strongly typed IDs that implement ISfid<TSelf>, register the converter factory for both Minimal APIs and controllers:
using Microsoft.AspNetCore.Http.Json;
using SfidNet.Serialization;
builder.Services.Configure<JsonOptions>(options =>
{
options.SerializerOptions.Converters.Add(new SfidJsonConverterFactory());
});
builder.Services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new SfidJsonConverterFactory());
});
The converters write IDs as JSON strings and accept either strings or integers on input. Sfid also implements IParsable<Sfid> and exposes Parse and TryParse, which makes route and query binding straightforward in Minimal APIs and MVC. Custom strongly typed IDs should add matching static parse methods if you want direct route and query binding for those types as well.
Entity Framework Core
For the default bigint mapping, you can enable the EF integration once on your DbContextOptionsBuilder and keep your entity configuration clean:
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(connectionString)
.UseSfidEntityFramework());
using Microsoft.EntityFrameworkCore;
using SfidNet.EntityFramework;
using SfidNet;
public sealed class OrderEntity
{
public Sfid Id { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<OrderEntity>(entity =>
{
entity.HasKey(order => order.Id);
});
}
If you call AssignSnowfakeKeys() during SaveChanges, primary keys typed as Sfid or another ISfid<TSelf> implementation are generated automatically even without HasSnowfakeKey().
Use HasSnowfakeKey() or HasSnowfakeConversion() only when you want to override the default convention, especially for string storage:
entity.Property(order => order.Id).HasSnowfakeKey(SfidStorageKind.String);
Documentation
- Reference guide: https://github.com/Cephalon-Labs/Sfid.Net/blob/master/snowfake.md
- Appsettings configuration guide: https://github.com/Cephalon-Labs/Sfid.Net/blob/master/docs/appsettings-configuration.md
- Benchmarking guide: https://github.com/Cephalon-Labs/Sfid.Net/blob/master/docs/benchmarking.md
- Validation snapshot: https://github.com/Cephalon-Labs/Sfid.Net/blob/master/docs/verification.md
- NuGet publishing guide: https://github.com/Cephalon-Labs/Sfid.Net/blob/master/docs/publishing-to-nuget.md
- Release notes draft: https://github.com/Cephalon-Labs/Sfid.Net/blob/master/docs/release-notes/1.0.1.md
Development
dotnet test Sfid.Net.slnx
dotnet run --project tests/Sfid.Benchmark/Sfid.Benchmark.csproj -c Release -- --filter *
pwsh ./eng/Pack.ps1
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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 is compatible. 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. |
-
net10.0
- Microsoft.EntityFrameworkCore (>= 10.0.5)
- Microsoft.Extensions.Caching.Memory (>= 10.0.5)
- Sfid.Net (>= 1.0.1)
-
net8.0
- Microsoft.EntityFrameworkCore (>= 8.0.2)
- Microsoft.Extensions.Caching.Memory (>= 9.0.0)
- Sfid.Net (>= 1.0.1)
-
net9.0
- Microsoft.EntityFrameworkCore (>= 9.0.10)
- Microsoft.Extensions.Caching.Memory (>= 9.0.10)
- Sfid.Net (>= 1.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Package version now follows AssemblyVersion, GitHub Releases publish artifacts to GitHub Packages, and local pack or publish scripts no longer require a manual version argument.