Sparkdo.IdGeneration.Abstractions
3.0.0-preview.1
dotnet add package Sparkdo.IdGeneration.Abstractions --version 3.0.0-preview.1
NuGet\Install-Package Sparkdo.IdGeneration.Abstractions -Version 3.0.0-preview.1
<PackageReference Include="Sparkdo.IdGeneration.Abstractions" Version="3.0.0-preview.1" />
<PackageVersion Include="Sparkdo.IdGeneration.Abstractions" Version="3.0.0-preview.1" />
<PackageReference Include="Sparkdo.IdGeneration.Abstractions" />
paket add Sparkdo.IdGeneration.Abstractions --version 3.0.0-preview.1
#r "nuget: Sparkdo.IdGeneration.Abstractions, 3.0.0-preview.1"
#:package Sparkdo.IdGeneration.Abstractions@3.0.0-preview.1
#addin nuget:?package=Sparkdo.IdGeneration.Abstractions&version=3.0.0-preview.1&prerelease
#tool nuget:?package=Sparkdo.IdGeneration.Abstractions&version=3.0.0-preview.1&prerelease
Sparkdo.IdGeneration.Abstractions
Sparkdo.IdGeneration.Abstractions 是 Id 生成能力的稳定公共契约包:一个泛型生成器接口、三个按 Id 类型专用的接口、一个按类型/名称解析的 provider 接口,以及 capability identity。零依赖(纯 BCL)、零服务注册、无扩展方法——引用它只声明「我要用 Id 生成器」,不绑定任何算法、DI 容器或锁实现。
默认实现与接线在 Sparkdo.IdGeneration(UUID v7 / ULID)和 Sparkdo.IdGeneration.Snowflake(Snowflake long);只需要面向接口编程的库(ORM 包装、领域层、多租户组件)引用本包即可。
契约一览
| 类型 | 成员 | 用途 |
|---|---|---|
IIdGenerator<out TId> |
TId Create() |
唯一的生成入口:同步产出一个 Id |
IGuidGenerator |
— | : IIdGenerator<Guid>,Guid Id 的专用服务键 |
IStringIdGenerator |
— | : IIdGenerator<string>,字符串 Id 的专用服务键 |
ILongIdGenerator |
— | : IIdGenerator<long>,64-bit 整数 Id 的专用服务键 |
IIdGeneratorProvider |
Get<TId>(string? name = null) |
按 Id 类型/名称解析生成器的统一入口 |
IdGenerationCapability |
const string Id = "Sparkdo.IdGeneration" |
稳定的 capability 标识 |
全部类型位于命名空间 Sparkdo.IdGeneration。
IIdGenerator<TId>
public interface IIdGenerator<out TId>
{
TId Create();
}
| 方面 | 契约 |
|---|---|
| 签名 | 同步、无参数、无 CancellationToken。生成 Id 不应是 I/O 操作:任何需要异步准备的前提(如 Snowflake worker lease)必须在此之前完成 |
| 幂等性 | 不幂等。每次调用返回新值,接口不提供「重试安全」语义 |
| 失败面 | 允许抛异常(默认实现全部 fail closed:状态或配置不合法时抛 InvalidOperationException,而不是返回可疑 Id) |
| null | TId = string 时应返回非 null 非空白值;接口层面无法用可空标注约束值类型与引用类型,实现方自行保证 |
| 线程安全 | 实现方必须保证并发安全:三种专用接口与泛型接口形态在默认实现中都注册为 Singleton,Create() 会被多线程并发调用(IIdGeneratorProvider 本体是 Transient,但它只是容器门面,不构成并发屏障) |
| 协变 | out TId 只在 TId 之间是引用转换时可向上宽化:IIdGenerator<string> 可当 IIdGenerator<object> 用;IIdGenerator<Guid>、IIdGenerator<long> 不能当 IIdGenerator<object>(装箱转换不满足协变前提)。按 Id 类型传递请用原始泛型参数 |
三个专用接口
IGuidGenerator / IStringIdGenerator / ILongIdGenerator 都是空标记接口,只做一件事:给 DI 一个按 Id 类型区分的唯一服务键。同一类型可能有多种实现(string 可以是 ULID,也可以是随机串;long 可以是 Snowflake,也可以是数据库号段),因此「类型级默认」用专用接口表达,「具名备选」用 keyed IIdGenerator<TId> 表达。
默认运行时包同时注册专用接口与泛型接口两种服务形态(IGuidGenerator 与 IIdGenerator<Guid> 是两条独立描述符,因此是两个各自的 Singleton 实例,而不是同一实例的两个别名),所以调用方可以任选注入方式;替换实现时两处都要覆盖才彻底,见下节。
IIdGeneratorProvider
public interface IIdGeneratorProvider
{
IIdGenerator<TId> Get<TId>(string? name = null);
}
| 输入 | 语义 |
|---|---|
name == null 或空白 |
取该 Id 类型的默认生成器:Guid → IGuidGenerator,string → IStringIdGenerator,long → ILongIdGenerator,其他类型 → IIdGenerator<TId> |
内置名 "guid" / "ulid" / "snowflake" |
与 TId 匹配时等价于默认分支;匹配按大小写不敏感(OrdinalIgnoreCase)。名称与 TId 不匹配时不跨类型短路,落到 keyed 分支 |
其他任意 name |
解析 keyed 服务 IIdGenerator<TId>(GetKeyedService),未命中抛 KeyNotFoundException |
var ids = serviceProvider.GetRequiredService<IIdGeneratorProvider>();
var a = ids.Get<Guid>().Create();
var b = ids.Get<Guid>("GUID").Create(); // 与 a 同一个实例
var c = ids.Get<int>("order-no").Create(); // keyed IIdGenerator<int>,实现由应用提供
用内置名注册 keyed 生成器是无效操作:AddKeyedSingleton<IIdGenerator<Guid>>(..., "guid") 永远不会被 Get<Guid>("guid") 读到(该名称被短路到 IGuidGenerator)。自定义名称请避开 guid、ulid、snowflake(大小写变体同样避开)。
默认实现解析的是接口而不是具体类:provider 不检查实现类型,也不缓存解析结果;long 的解析依赖 Sparkdo.IdGeneration.Snowflake 包是否注册了 ILongIdGenerator,未注册时抛 DI 标准的 InvalidOperationException("No service for type ..."),与「名称未命中」的 KeyNotFoundException 是两类故障,排查时据此区分。
IdGenerationCapability
public static class IdGenerationCapability
{
public const string Id = "Sparkdo.IdGeneration";
}
capability 的稳定标识,供需要声明「本组件依赖 Id 生成能力」的清单、诊断或组合根使用。它是常量而不是枚举:值不随包版本变化,三个运行时包共用同一个 Id。
面向实现者的备注
- 只提供契约:本包不含实现、不含 DI 扩展、不引用
Microsoft.Extensions.*。引用它不会让容器多出任何服务。 Create()里禁止 I/O、禁止Task.Wait/.Result、禁止 sleep 等待时钟。需要异步准备就把准备动作放进独立的生命周期钩子(参考SnowflakeWorkerStartupTask的做法)。- 建议保持 fail closed:前提不成立时抛异常,而不是返回可能重复或降质的 Id。默认实现的行为基线是「宁可拒绝生成,也不生成可疑 Id」。
- 若实现是 Singleton,必须无共享可变状态或用锁保护(
SnowflakeIdState用单把锁保护 sequence 与逻辑时间)。 - 想让自定义实现顶掉默认实现,请在调用
AddSparkdoIdGeneration()/AddSparkdoIdGenerationSnowflake()之前注册(两个 Add 方法全部TryAdd);泛型形态IIdGenerator<TId>与专用接口形态是两个独立描述符,需要分别覆盖。 - 契约全部 AOT / trimming 友好:无反射、无动态代码、无
params/装箱热点。
边界
- 不承诺 Id 的不可预测性、不承诺同毫秒单调、不承诺跨进程唯一性由接口保证——这些属于具体实现(见
Sparkdo.IdGeneration与Sparkdo.IdGeneration.Snowflake的 README)。 - 不提供异步生成器接口(
CreateAsync)、不提供批量CreateMany、不提供 Id 解析工具方法。 - 不含 worker id 分配 SPI(
ISnowflakeWorkerIdProvider)与SnowflakeWorkerLease——它们随 Snowflake 实现包发布,属于该实现的可替换点。
安装
dotnet add package Sparkdo.IdGeneration.Abstractions
需要默认实现与 DI 接线时改引用 Sparkdo.IdGeneration(已含对本包的传递引用)。
本文即包内 README.md(PackageReadmeFile,实测随 nupkg 发布),并与 Sparkdo.IdGeneration.Abstractions.xml 一起提供 IntelliSense。因此文中只以包名明文引用其他包,不使用相对路径链接;验证命令见域根 README(dotnet test src/id-generation/Sparkdo.IdGeneration.slnx)。
| 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. net11.0 is compatible. |
-
net10.0
- No dependencies.
-
net11.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Sparkdo.IdGeneration.Abstractions:
| Package | Downloads |
|---|---|
|
Sparkdo.IdGeneration
Sparkdo 的 UUID v7 与 ULID Id 生成运行时(Snowflake 见 Sparkdo.IdGeneration.Snowflake)。 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.0-preview.1 | 71 | 10/30/2026 |
| 2.0.0-preview.2 | 111 | 7/20/2026 |
| 2.0.0-preview.1 | 88 | 7/18/2026 |