BugFree.Security.Key
1.1.2026.121-beta1051
dotnet add package BugFree.Security.Key --version 1.1.2026.121-beta1051
NuGet\Install-Package BugFree.Security.Key -Version 1.1.2026.121-beta1051
<PackageReference Include="BugFree.Security.Key" Version="1.1.2026.121-beta1051" />
<PackageVersion Include="BugFree.Security.Key" Version="1.1.2026.121-beta1051" />
<PackageReference Include="BugFree.Security.Key" />
paket add BugFree.Security.Key --version 1.1.2026.121-beta1051
#r "nuget: BugFree.Security.Key, 1.1.2026.121-beta1051"
#:package BugFree.Security.Key@1.1.2026.121-beta1051
#addin nuget:?package=BugFree.Security.Key&version=1.1.2026.121-beta1051&prerelease
#tool nuget:?package=BugFree.Security.Key&version=1.1.2026.121-beta1051&prerelease
BugFree.Security.Key
企业级密钥全生命周期管理组件,支持对称和非对称密钥的存储、轮换和泄露检测
概述
BugFree.Security.Key 是 BugFree 框架的密钥管理组件,提供密钥的完整生命周期管理功能。采用完全委托模式,零依赖 BugFree.Security,专注于密钥的存储、轮换、访问控制和策略管理。
核心特性
- 🔐 全生命周期管理:密钥创建、存储、轮换、归档、销毁
- 🔄 自动轮换:基于时间、使用次数或策略的自动密钥轮换
- 💾 多种存储后端:文件存储(默认)、内存存储
- 📊 密钥版本控制:支持多版本密钥共存,加密用最新,解密用指定版本
- 🎯 完全委托模式:零依赖
BugFree.Security,密钥生成由调用方提供 - 🚀 依赖注入友好:原生支持 Microsoft.Extensions.DependencyInjection
- 🔒 安全密钥句柄:
SafeKeyMaterialHandle确保密钥材料安全存储在非托管内存 - 🌐 跨平台支持:完全支持 Windows、Linux、macOS(.NET 8+)
目标框架
net8.0和net10.0多目标框架
设计理念
完全委托模式:本组件不依赖任何加密算法实现,密钥的生成完全由调用方通过委托提供。这使得组件可以与任何加密库(如 BugFree.Security、BouncyCastle、系统 API 等)无缝集成。
v8.0 重构:
- 密钥生成器从构造函数移至
ResolveForKey方法参数,实现按需生成 SymmetricKeyManager和AsymmetricKeyManager完全分离,各自独立管理ResolveForKey方法直接返回ReadOnlySpan<Byte>,简化密钥访问流程
对称/非对称分离:对称密钥和非对称密钥管理器完全分离,各自独立管理,提供更清晰的职责划分和类型安全。
架构设计
核心组件
BugFree.Security.Key
├── SymmetricKeyManager # 对称密钥管理器(ISymmetricKeyManager)
├── AsymmetricKeyManager # 非对称密钥管理器(IAsymmetricKeyManager)
├── SafeKeyMaterialHandle # 安全密钥材料句柄(非托管内存管理)
├── Abstractions/
│ ├── ISymmetricKeyManager # 对称密钥管理器接口
│ ├── IAsymmetricKeyManager # 非对称密钥管理器接口
│ ├── IKeyStore<T> # 泛型密钥存储接口
│ ├── IKeyResolver<T> # 泛型密钥解析器接口
│ ├── IKeyRotator<T> # 泛型密钥轮换器接口
│ └── Delegate.cs # 委托类型定义
├── Core/
│ ├── DefaultKeyResolver<T> # 默认密钥解析器实现
│ ├── DefaultSymmetricKeyRotator # 对称密钥轮换器
│ ├── DefaultAsymmetricKeyRotator # 非对称密钥轮换器
│ └── Store/
│ ├── FileKeyStore<T> # 文件存储实现(泛型)
│ └── MemoryKeyStore<T> # 内存存储实现(泛型)
├── Models/
│ ├── KeyRecord # 密钥记录基类
│ ├── SymmetricKeyRecord # 对称密钥记录(含 Key 属性)
│ ├── AsymmetricKeyRecord # 非对称密钥记录(含 PublicKey/PrivateKey 属性)
│ ├── KeyMetadata # 密钥元数据(不含密钥材料)
│ ├── KeyPolicy # 密钥策略
│ └── KeyStatus # 密钥状态枚举
└── ServiceCollectionExtensions.cs # DI 扩展方法
设计模式
- 门面模式(Facade):
SymmetricKeyManager和AsymmetricKeyManager作为统一入口 - 策略模式(Strategy):通过泛型
IKeyStore<T>支持多种存储后端 - 委托模式(Delegate):密钥生成由调用方通过参数提供,实现零依赖和按需生成
- 泛型设计:
IKeyStore<T>、IKeyResolver<T>等泛型接口提供类型安全 - 仓库模式(Repository):
IKeyStore<T>提供密钥持久化抽象
核心概念
密钥生命周期
创建 → Active(活跃) → DecryptOnly(仅解密,已轮换) → Retired(退役) → 销毁
↓
Compromised(已泄露) → 强制轮换
密钥状态(KeyStatus)
| 状态 | 说明 | 是否可用于加密/签名 | 是否可用于解密/验签 |
|---|---|---|---|
| Active | 活跃状态,当前使用的密钥 | ✅ 是 | ✅ 是 |
| DecryptOnly | 已轮换,仅用于解密历史数据 | ❌ 否 | ✅ 是 |
| Retired | 已退役,不再用于任何操作 | ❌ 否 | ❌ 否 |
| Compromised | 已泄露,必须立即轮换 | ❌ 否 | ⚠️ 谨慎使用 |
密钥策略(KeyPolicy)
public class KeyPolicy
{
/// <summary>轮换间隔,默认 90 天</summary>
public TimeSpan RotationInterval { get; set; } = TimeSpan.FromDays(90);
/// <summary>最大使用次数,默认 1000 次</summary>
public Int32 MaxUsageCount { get; set; } = 1000;
/// <summary>过期日期,可选</summary>
public DateTime? ExpirationDate { get; set; }
/// <summary>是否启用自动轮换,默认 true</summary>
public Boolean EnableAutoRotation { get; set; } = true;
}
存储实现
| 存储类型 | 适用场景 | 线程安全 | 持久化 |
|---|---|---|---|
| File | 生产环境(默认) | ✅ 是 | ✅ 是 |
| Memory | 开发/测试环境 | ✅ 是 | ❌ 否 |
文件存储(FileKeyStore<T>):
- 泛型设计,支持
SymmetricKeyRecord和AsymmetricKeyRecord - 每个
KeyId + Version对应一个 JSON 文件 - 文件命名规则:
{keyId}_v{version}.json - 默认存储目录:
AppContext.BaseDirectory/KeyStore - 使用内存缓存提高读取性能
安全密钥句柄(SafeKeyMaterialHandle)
跨平台安全:
- 完全支持 Windows、Linux、macOS
- 使用
Marshal.AllocHGlobal进行平台无关的内存分配 - 释放时自动清零内存,防止密钥泄露到内存转储中
- 继承
SafeHandleZeroOrMinusOneIsInvalid,确保确定性释放
零开销访问:
- 提供
DangerousGetSpan()方法返回ReadOnlySpan<Byte>(零拷贝) - 提供
DangerousGetMemory()方法返回ReadOnlyMemory<Byte>(数据副本) - 密钥存储在非托管内存中,避免 CLR 垃圾回收器的可见性
快速开始
基础用法
1. 配置依赖注入
using BugFree.Security.Key;
using BugFree.Security.Key.Abstractions;
using Microsoft.Extensions.DependencyInjection;
// 配置依赖注入
var services = new ServiceCollection();
// 注册对称密钥管理器(v8.0:密钥生成器通过参数传入,非构造函数)
services.AddSymmetricKeyManagerCore(
keyStore: new FileKeyStore<SymmetricKeyStore>("./keys")
);
// 注册非对称密钥管理器
services.AddAsymmetricKeyManagerCore(
keyStore: new FileKeyStore<AsymmetricKeyStore>("./keys")
);
var serviceProvider = services.BuildServiceProvider();
var symmetricKeyManager = serviceProvider.GetRequiredService<ISymmetricKeyManager>();
var asymmetricKeyManager = serviceProvider.GetRequiredService<IAsymmetricKeyManager>();
2. 对称密钥加密/解密
using BugFree.Security;
using BugFree.Security.Abstractions.Algorithms.Symmetric;
using System.Security.Cryptography;
// 准备数据
var plaintext = Encoding.UTF8.GetBytes("Sensitive Data");
var symmetricKeyManager = new SymmetricKeyManager();
// 加密数据(v8.0:keyGenerator 作为参数传入,首次自动生成密钥)
var key = symmetricKeyManager.ResolveForKey(
keyId: "user-data-key",
keyGenerator: () =>
{
var keySize = 32; // AES-256
return ("AES-GCM", RandomNumberGenerator.GetBytes(keySize));
});
// 使用密钥进行加密
var algorithm = AesGcm.Create();
var nonce = new Byte[12];
var tag = new Byte[16];
var ciphertext = new Byte[plaintext.Length];
RandomNumberGenerator.GetBytes(nonce);
algorithm.Encrypt(nonce, plaintext, ciphertext, tag);
Console.WriteLine($"Encrypted successfully with key version: {key.Version}");
// 解密数据(指定密钥版本)
var version = 1; // 从加密时保存
var decryptKey = symmetricKeyManager.ResolveForKey("user-data-key", version);
var plaintextBytes = new Byte[ciphertext.Length];
algorithm.Decrypt(nonce, ciphertext, tag, plaintextBytes);
Console.WriteLine($"Decrypted: {Encoding.UTF8.GetString(plaintextBytes)}");
3. 非对称密钥签名/验签
using BugFree.Security;
using BugFree.Security.Abstractions.Algorithms.Asymmetric;
var asymmetricKeyManager = new AsymmetricKeyManager();
var asymmetricService = AsymmetricService.Instance;
// 签名数据(v8.0:keyGenerator 作为参数传入)
var document = Encoding.UTF8.GetBytes("Important Document");
var privateKey = asymmetricKeyManager.ResolveForKey(
keyId: "signing-key",
isPublicKey: false, // 使用私钥
keyGenerator: () =>
{
var keyPair = asymmetricService.BuildKeyPairGeneratorProvider(
KeyPairGeneratorProviderType.ECDSA
).GenerateKeyPair();
return ("ECDSA", keyPair.PublicKey, keyPair.PrivateKey);
}
);
// 使用私钥签名
var signature = asymmetricService.Sign(
SignatureProviderType.ECDSA,
document,
privateKey
);
Console.WriteLine($"Signed successfully");
// 验证签名(使用公钥)
var publicKey = asymmetricKeyManager.ResolveForKey(
keyId: "signing-key",
version: 1,
isPublicKey: true
);
var isValid = asymmetricService.Verify(
SignatureProviderType.ECDSA,
document,
signature,
publicKey
);
Console.WriteLine($"Signature valid: {isValid}");
4. 密钥查询和管理
// 删除指定版本的密钥
symmetricKeyManager.Delete("user-data-key", version: 1);
// 删除密钥的所有版本
symmetricKeyManager.Delete("user-data-key");
高级用法
自定义密钥策略
// 使用自定义策略覆盖默认策略
var customPolicy = new KeyPolicy
{
RotationInterval = TimeSpan.FromDays(30),
MaxUsageCount = 100,
EnableAutoRotation = true
};
var key = symmetricKeyManager.ResolveForKey(
keyId: "my-key",
keyGenerator: () => ("AES", RandomNumberGenerator.GetBytes(32)),
policy: customPolicy // 覆盖默认策略
);
自定义密钥存储
using BugFree.Security.Key.Abstractions;
// 实现 IKeyStore<T> 接口
public class CustomKeyStore : IKeyStore<SymmetricKeyRecord>
{
public SymmetricKeyRecord? GetKey(String keyId, Int32 version)
{
// 从自定义存储中读取密钥
throw new NotImplementedException();
}
public SymmetricKeyRecord? GetLatestKey(String keyId)
{
// 获取最新版本的密钥
throw new NotImplementedException();
}
public KeyMetadata? GetMetadata(String keyId, Int32 version)
{
// 获取密钥元数据
throw new NotImplementedException();
}
public void Save(SymmetricKeyRecord key)
{
// 保存密钥到自定义后端
throw new NotImplementedException();
}
public void Delete(String keyId, Int32? version = null)
{
// 从自定义后端删除密钥
throw new NotImplementedException();
}
public IEnumerable<KeyMetadata> GetAllMetadata()
{
// 返回所有密钥的元数据
throw new NotImplementedException();
}
public void RemoveExpired(Func<KeyMetadata, Boolean> expired)
{
// 移除过期记录
throw new NotImplementedException();
}
}
// 使用自定义存储
var manager = new SymmetricKeyManager(new CustomKeyStore());
使用 KeyedCryptoService(推荐)
BugFree.Security 提供了基于 SymmetricKeyManager 和 AsymmetricKeyManager 的门面服务:
using BugFree.Security;
using BugFree.Security.Abstractions.Algorithms.Symmetric;
using BugFree.Security.Key;
// 创建密钥管理器
var symmetricKeyManager = new SymmetricKeyManager();
var asymmetricKeyManager = new AsymmetricKeyManager();
// 创建门面服务
var symmetricService = new KeyedCryptoSymmetricService(symmetricKeyManager);
var asymmetricService = new KeyedCryptoAsymmetricService(asymmetricKeyManager);
// 对称加密(自动生成并轮换密钥)
var plaintext = Encoding.UTF8.GetBytes("Sensitive Data");
var encryptResult = symmetricService.Encrypt(
SymmetricType.AesGcm,
"user-data-key",
plaintext
);
Console.WriteLine($"Encrypted with key version: {encryptResult.Version}");
// 对称解密
var decrypted = symmetricService.Decrypt(
SymmetricType.AesGcm,
encryptResult.Value.Ciphertext,
"user-data-key",
encryptResult.Version,
new SymmetricDecryptOptions
{
Nonce = encryptResult.Value.Nonce,
Tag = encryptResult.Value.Tag
}
);
Console.WriteLine($"Decrypted: {Encoding.UTF8.GetString(decrypted)}");
安全注意事项
密钥存储
- ✅ 文件存储:默认使用文件存储,密钥以 JSON 格式保存到磁盘
- ✅ 访问控制:确保密钥存储目录有正确的文件系统权限(仅允许应用程序访问)
- ✅ 生产环境:推荐使用专业密钥管理服务(HSM/KMS)
- ❌ 内存存储:仅用于开发和测试,不适用于生产环境(应用重启后丢失)
密钥轮换
- ✅ 定期轮换:推荐对称密钥 90 天,非对称密钥 180 天
- ✅ 使用次数限制:设置合理的
MaxUsageCount防止密钥过度使用 - ✅ 平滑轮换:新密钥用于加密,旧密钥保留用于解密历史数据
- ⚠️ 归档策略:制定密钥归档和销毁策略
- ⚠️ 保留期限:旧密钥必须保留足够长时间以解密历史数据
密钥访问
- ✅ 最小权限:仅授予必要的密钥访问权限
- ✅ 密钥分离:加密密钥和签名密钥分离使用
- ✅ ReadOnlySpan:使用
ReadOnlySpan<Byte>确保密钥材料的安全访问 - ❌ 日志记录:禁止在日志中输出密钥材料
- ❌ 异常处理:密钥访问异常不应泄露密钥信息
密钥生成
- ✅ 强随机数:使用
RandomNumberGenerator或RandomNumberGenerator.GetBytes生成密钥 - ✅ 密钥长度:AES 推荐 256 位(32 字节),RSA 推荐 2048 位以上
- ✅ 算法选择:优先使用 AES-GCM、ECDSA、Ed25519 等现代算法
- ✅ 唯一性:每个密钥 ID 应该有唯一且描述性的名称
跨平台安全
- ✅ SafeKeyMaterialHandle:使用安全句柄管理非托管内存中的密钥材料
- ✅ 自动清零:句柄释放时自动清零内存,防止内存转储泄露
- ✅ 零拷贝访问:通过
DangerousGetSpan()提供零开销的只读访问 - ⚠️ 句柄生命周期:调用者必须确保在使用期间不释放句柄
最佳实践
1. 密钥命名规范
// 好的命名(包含用途和环境)
"user-data-encryption-prod"
"api-signing-key-staging"
"session-key-cache"
"database-encryption-primary"
// 避免的命名(过于简单或含糊)
"key1"
"test"
"my-key"
"encryption"
2. 密钥策略配置
// 生产环境策略
var productionPolicy = new KeyPolicy
{
RotationInterval = TimeSpan.FromDays(90),
MaxUsageCount = 1000,
EnableAutoRotation = true,
ExpirationDate = DateTime.UtcNow.AddYears(1)
};
// 开发环境策略
var developmentPolicy = new KeyPolicy
{
#if DEBUG
RotationInterval = TimeSpan.FromSeconds(10), // 便于测试
#else
RotationInterval = TimeSpan.FromDays(90),
#endif
MaxUsageCount = 10000, // 宽松限制
EnableAutoRotation = true
};
// 高安全场景策略
var highSecurityPolicy = new KeyPolicy
{
RotationInterval = TimeSpan.FromDays(30), // 更短的轮换周期
MaxUsageCount = 100, // 更严格的使用限制
EnableAutoRotation = true,
ExpirationDate = DateTime.UtcNow.AddMonths(6)
};
3. 密钥生命周期管理
// 1. 加密数据(自动使用最新密钥)
var encryptResult = symmetricService.Encrypt(
SymmetricType.AesGcm,
"my-encryption-key",
Encoding.UTF8.GetBytes("Sensitive Data")
);
// 2. 保存密钥版本号(与密文一起)
SaveToDatabase(encryptResult.Value, encryptResult.Version);
// 3. 解密时使用相同版本
var decrypted = symmetricService.Decrypt(
SymmetricType.AesGcm,
encryptResult.Value.Ciphertext,
"my-encryption-key",
encryptResult.Version,
new SymmetricDecryptOptions
{
Nonce = encryptResult.Value.Nonce,
Tag = encryptResult.Value.Tag
}
);
// 4. 删除过期密钥(当确定不再需要时)
symmetricKeyManager.Delete("my-encryption-key", version: 1);
4. 错误处理
try
{
var key = symmetricKeyManager.ResolveForKey(
"my-key",
keyGenerator: () => ("AES", RandomNumberGenerator.GetBytes(32))
);
// 使用密钥...
}
catch (ArgumentNullException ex)
{
// 密钥 ID 为空或密钥生成器为空
logger.LogError($"Invalid parameter: {ex.ParamName}");
}
catch (KeyNotFoundException ex)
{
// 密钥不存在(首次使用会自动创建)
logger.LogWarning($"Key not found: {ex.Message}");
}
catch (Exception ex)
{
// 其他错误(如密钥访问失败)
logger.LogError($"Key operation failed: {ex.Message}");
throw;
}
API 参考
SymmetricKeyManager
public sealed class SymmetricKeyManager : ISymmetricKeyManager
{
// 获取默认密钥策略
public KeyPolicy DefaultPolicy { get; }
// 删除密钥
public void Delete(String keyId, Int32? version = null);
// 使用密钥执行操作(自动轮换,使用最新版本)
// v8.0:密钥生成器通过参数传入
public ReadOnlySpan<Byte> ResolveForKey(
String keyId,
SymmetricKeyGeneratorDelegate keyGenerator,
KeyPolicy? policy = null
);
// 使用指定版本的密钥执行操作
public ReadOnlySpan<Byte> ResolveForKey(String keyId, Int32 version);
}
AsymmetricKeyManager
public sealed class AsymmetricKeyManager : IAsymmetricKeyManager
{
// 获取默认密钥策略
public KeyPolicy DefaultPolicy { get; }
// 删除密钥
public void Delete(String keyId, Int32? version = null);
// 使用密钥执行操作(自动轮换,使用最新版本)
// v8.0:密钥生成器通过参数传入
public ReadOnlySpan<Byte> ResolveForKey(
String keyId,
Boolean isPublicKey,
AsymmetricKeyGeneratorDelegate keyGenerator,
KeyPolicy? policy = null
);
// 使用指定版本的密钥执行操作
public ReadOnlySpan<Byte> ResolveForKey(
String keyId,
Int32 version,
Boolean isPublicKey
);
}
SafeKeyMaterialHandle
public sealed class SafeKeyMaterialHandle : SafeHandleZeroOrMinusOneIsInvalid
{
// 获取密钥的 ReadOnlySpan<Byte> 视图(零开销)
public ReadOnlySpan<Byte> DangerousGetSpan();
// 获取密钥的 ReadOnlyMemory<Byte> 视图
public ReadOnlyMemory<Byte> DangerousGetMemory();
// 获取密钥数据的长度(字节)
public Int32 Length { get; }
// 获取一个值,指示密钥数据是否为空
public Boolean IsEmpty { get; }
// 释放句柄关联的非托管内存
protected override Boolean ReleaseHandle();
}
依赖项
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.2" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.2" />
外部依赖说明
- Microsoft.Extensions.DependencyInjection.Abstractions:依赖注入抽象
- Microsoft.Extensions.Options:选项模式支持
- 零 BugFree.Security 依赖:密钥生成完全由调用方通过委托提供(完全委托模式)
版本历史
v8.0(当前版本)
重大重构:
- ✅ 对称和非对称密钥管理器完全分离
- ✅ 泛型化的
IKeyStore<T>接口 - ✅ 分离的
SymmetricKeyRecord和AsymmetricKeyRecord - ✅ 新增
SafeKeyMaterialHandle安全密钥句柄 - ✅ 跨平台支持(Windows、Linux、macOS)
- ✅ 密钥生成器通过参数传入:
ResolveForKey方法接受keyGenerator委托,实现按需生成
API 简化:
- ✅
ResolveForKey方法直接返回ReadOnlySpan<Byte>,不再使用KeyHandler<T>委托 - ✅ 构造函数不再需要
keyGenerator参数,简化依赖注入配置 - ✅ DI 注册方法简化为
AddSymmetricKeyManagerCore和AddAsymmetricKeyManagerCore
破坏性变更:
KeyManager拆分为SymmetricKeyManager和AsymmetricKeyManagerEnsureFreshSymmetricKey和EnsureFreshAsymmetricKey方法移除,使用ResolveForKey替代ResolveForEncryption、ResolveForDecryption、ResolveForSigning、ResolveForVerification方法移除,统一使用ResolveForKeyKeyHandler<T>委托模式改为直接返回ReadOnlySpan<Byte>- DI 注册方法改为
AddSymmetricKeyManagerCore和AddAsymmetricKeyManagerCore,不再需要keyGenerator参数
迁移指南:
// 旧版本(v7.x)
var keyGenerator = () => ("AES", new ReadOnlyMemory<Byte>(key));
var manager = new SymmetricKeyManager(keyGenerator);
var result = manager.ResolveForKey<String>("my-key", keySpan => EncryptData(keySpan));
// 新版本(v8.0)
var manager = new SymmetricKeyManager();
var keySpan = manager.ResolveForKey("my-key", keyGenerator: () => ("AES", new ReadOnlyMemory<Byte>(key)));
var result = EncryptData(keySpan);
路线图
| 功能 | 当前状态 | 计划 |
|---|---|---|
| 文件存储 | ✅ 已实现 | 优化加密性能 |
| 内存存储 | ✅ 已实现 | 增加缓存策略 |
| SafeKeyMaterialHandle | ✅ 已实现 | 跨平台验证 |
| Azure Key Vault | ❌ 未实现 | 计划支持 |
| AWS KMS | ❌ 未实现 | 计划支持 |
| HashiCorp Vault | ❌ 未实现 | 计划支持 |
| 密钥导入/导出 | ❌ 未实现 | 计划支持 |
| 密钥备份/恢复 | ❌ 未实现 | 计划支持 |
| 密钥权限管理 | ❌ 未实现 | 计划支持 RBAC |
| 访问日志审计 | ❌ 未实现 | 计划支持 |
相关组件
- BugFree.Security:安全加密组件库
- BugFree.Core:核心平台抽象和工具
贡献指南
- 提交 PR 前请确保添加相应的单元测试
- 若扩展
IKeyStore<T>,请提供完整的文档和示例 - 密钥存储实现必须考虑线程安全性
- 遵循现有的代码风格和命名规范
许可证
本项目遵循 BugFree 框架的许可证。
联系方式
如有问题或建议,请联系邮箱:ligengrong@hotmail.com
最后更新: 2026-01-20 版本: 1.1.2026.120 目标框架: net8.0;net10.0 依赖: 零依赖 BugFree.Security(完全委托模式) 跨平台: Windows、Linux、macOS
| 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 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. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.2)
- Microsoft.Extensions.Options (>= 10.0.2)
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.2)
- Microsoft.Extensions.Options (>= 10.0.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.2026.121-beta1051 | 205 | 1/21/2026 |
| 1.1.2026.120-beta1330 | 73 | 1/20/2026 |
| 1.1.2026.120-beta1028 | 73 | 1/20/2026 |
| 1.1.2026.118-beta1029 | 100 | 1/18/2026 |