Inkslab 是一套简单、高效、模块化的 .NET 轻量基础设施框架。它由若干独立 NuGet 包组成,围绕 SingletonPools 单例池与 XStartup 启动机制协同工作:面向接口、约定优先、按需引用、零侵入替换。
- 统一 API 设计:所有模块遵循
接口契约 + 默认实现 + 单例池注册的一致模式。 - 自动启动:
XStartup扫描并按Code/Weight顺序执行所有IStartup。 - 语法糖扩展:字符串、集合、日期、枚举、类型、反射、加密等扩展方法位于 src/Inkslab/Extentions。
- 多框架支持:
net461/netstandard2.1/net6.0。 - 零侵入替换:任何默认实现都可以通过
SingletonPools.TryAdd<TService, TImplementation>()在启动前替换。
inkslab/
├─ src/
│ ├─ Inkslab/ # 核心:单例池、启动、扩展方法、KeyGen、PagedList、IMapper/IJsonHelper/IConfigHelper 契约
│ ├─ Inkslab.Config/ # IConfigHelper 默认实现(配置文件读取)
│ ├─ Inkslab.Json/ # IJsonHelper 默认实现(基于 Newtonsoft.Json)
│ ├─ Inkslab.Map/ # IMapper 默认实现(约定优先对象映射)
│ ├─ Inkslab.DI/ # IServiceCollection 自动装配扩展
│ └─ Inkslab.Net/ # HTTP 请求工厂 IRequestFactory
└─ tests/ # 对应各模块的单元测试
| 包 | 版本 | 下载 | 文档 | 用途 |
|---|---|---|---|---|
Inkslab |
本文 | 核心基础设施 | ||
Inkslab.Config |
Inkslab.Config.md | 配置文件读取 | ||
Inkslab.Json |
Inkslab.Json.md | JSON 序列化 | ||
Inkslab.Map |
Inkslab.Map.md | 对象映射 | ||
Inkslab.DI |
Inkslab.DI.md | 依赖注入扩展 | ||
Inkslab.Net |
Inkslab.Net.md | HTTP 请求 |
dotnet add package Inkslab框架使用 XStartup 发现并执行所有 IStartup(含其它 Inkslab.* 包的默认注册)。
using Inkslab;
using (var startup = new XStartup())
{
startup.DoStartup();
}XStartup 构造函数支持按程序集模式、程序集实例、类型集合进行范围限定:
new XStartup(); // 扫描基目录所有程序集
new XStartup("MyApp.*.dll"); // 按通配符
new XStartup(new[] { typeof(Program).Assembly });仅添加 Inkslab 不会带入 JSON/Map/Net/Config 实现。按需引用即可;引用后无需任何代码,XStartup 会自动注册默认实现到单例池。
dotnet add package Inkslab.Json # 注册 IJsonHelper
dotnet add package Inkslab.Config # 注册 IConfigHelper
dotnet add package Inkslab.Map # 注册 IMapper
dotnet add package Inkslab.Net # 通过 DI 注入 IRequestFactory
dotnet add package Inkslab.DI # 为 IServiceCollection 提供自动装配扩展单例池 SingletonPools
所有服务契约的统一注册与获取入口。
// 注册(返回 false 代表已注册)
SingletonPools.TryAdd<IJsonHelper, CustomJsonHelper>();
SingletonPools.TryAdd<IMyService>(new MyServiceImpl());
SingletonPools.TryAdd<IMyService>(() => new MyServiceImpl());
// 获取
var json = SingletonPools.Singleton<IJsonHelper>();| 方法 | 说明 |
|---|---|
TryAdd<TService>() |
注册无参默认实现 |
TryAdd<TService>(TService instance) |
注册已有实例 |
TryAdd<TService>(Func<TService> factory) |
注册工厂 |
TryAdd<TService, TImplementation>() |
注册契约-实现映射 |
Singleton<TService>() |
获取单例,未注册时按约定创建 |
启动项契约 IStartup
public interface IStartup
{
int Code { get; } // 启动阶段编号(排序依据)
int Weight { get; } // 同阶段内权重
void Startup(); // 注册逻辑(通常向 SingletonPools 注册默认实现)
}实现此接口 + 放入被扫描的程序集即可自动被 XStartup 执行。
主键生成 KeyGen
默认基于雪花算法。
long id = KeyGen.Id(); // long 主键
Key key = KeyGen.New(); // 值对象封装
Key key2 = KeyGen.New(id); // 从已有 long 还原
// 自定义机房/机器号(启动前注册)
SingletonPools.TryAdd(new KeyOptions(workerId: 1, datacenterId: 1));PagedList<T>:PageIndex/PageSize/Total。LazyList<T>:Offset/HasNext,适合游标式加载。
var page = new PagedList<User>(users, pageIndex: 1, pageSize: 20, total: 135);命名风格 NamingType
public enum NamingType
{
Normal = 0, // 原样
CamelCase = 1, // userName
SnakeCase = 2, // user_name
PascalCase = 3, // UserName
KebabCase = 4 // user-name
}
"UserName".ToNamingCase(NamingType.SnakeCase); // => "user_name"Lru<T>/Lru<TKey, TValue>:线程安全 LRU 淘汰。Lfu<T>/Lfu<TKey, TValue>:线程安全 LFU 淘汰。- 共用
IEliminationAlgorithm<T>契约,便于替换。
异步锁 AsynchronousLock
悲观异步锁(基于 SemaphoreSlim):
using (await _lock.AcquireAsync())
{
// 临界区
}| 异常 | 用途 |
|---|---|
CodeException |
基础异常(带错误码) |
BusiException |
业务异常 |
ServException |
服务层异常 |
SyntaxException |
语法/配置错误 |
程序集发现 AssemblyFinder
var asms = AssemblyFinder.Find("MyApp.*.dll");全部位于
Inkslab命名空间(部分定义在System以实现全局可见)。
| 分类 | 文件 | 主要方法 |
|---|---|---|
| 字符串 | StringExtensions |
ToNamingCase · ToPascalCase · ToSnakeCase · ToCamelCase · ToKebabCase · IsNull · IsEmpty · IsMail · Format · Config<T> · StringSugar |
| 集合 | IEnumerableExtentions |
Join · ForEach · Distinct · AlignOverall · Align · ZipEach · AlignEach · JoinEach |
| 日期时间 | DateTimeExtensions |
StartOfDay/Week/Month/Quarter/Year · EndOfDay/... · IsToday/Yesterday/Tomorrow · IsWeekday/Weekend · IsSameDay/Week/Month/Year · WeekOfYear · IsLeapYear · NextWeekday · PreviousWeekday · WorkingDays · AddWorkingDays · ToUnixTimestamp[Milliseconds] · FromUnixTimestamp[Milliseconds] · GetAge · RoundTo/FloorTo/CeilingTo |
| 枚举 | EnumExtensions |
GetText · ToInt32 · ToInt64 · ToValueString · ToValues |
| 类型 | TypeExtensions |
IsMini · IsSimple · IsNullable · IsKeyValuePair · IsAmongOf · IsLike |
| 反射 | ReflectionExtensions |
IsIgnore · GetDescription |
| 加密 | CryptoExtensions |
Md5 · Encrypt · Decrypt(CryptoKind.DES / AES / ...) |
日期周边界约定:
UTC以周日为一周起始,Local以周一为起始。
"UserName".ToSnakeCase(); // "user_name"
"user_name".ToPascalCase(); // "UserName"
var conn = "ConnectionStrings:Default".Config<string>();
var cfg = "AppSettings".Config<AppConfig>();var ordered = array2.AlignOverall(array1).ToList(); // array2 按 array1 重排
array1.JoinEach(array2, x => x, y => y.Id, (x, y) => { /* 内连接回调 */ });"password".Md5();
var cipher = "data".Encrypt("Test@*$!", CryptoKind.DES);
var plain = cipher.Decrypt("Test@*$!", CryptoKind.DES);string json = JsonHelper.ToJson(obj, NamingType.CamelCase, indented: true);
var obj2 = JsonHelper.Json<MyDto>(json, NamingType.CamelCase);
var dbConn = "ConnectionStrings:Default".Config<string>();
var dto = Mapper.Map<UserDto>(user);任何 IXxxHelper 都可在启动前通过 SingletonPools.TryAdd 替换:
public class MyJsonHelper : IJsonHelper { /* ... */ }
// 必须在 XStartup.DoStartup() 之前调用
SingletonPools.TryAdd<IJsonHelper, MyJsonHelper>();
using var startup = new XStartup();
startup.DoStartup();| 项目 | 覆盖范围 |
|---|---|
tests/Inkslab.Tests |
核心扩展、集合、加密、日期、异步锁等 |
tests/Inkslab.Config.Tests |
配置读取 |
tests/Inkslab.Json.Tests |
JSON 序列化 |
tests/Inkslab.Map.Tests |
对象映射 |
tests/Inkslab.DI.Tests |
自动装配(ASP.NET Core 宿主) |
tests/Inkslab.Net.Tests |
HTTP 请求 |
运行:
dotnet test- 版本管理:
Directory.Build.props统一Version=1.2.23、LangVersion=9.0、TreatWarningsAsErrors=true、GenerateDocumentationFile=true。 - 打包:
build.ps1对 6 个包逐个dotnet pack --configuration Release到.nupkgs/。 - CI:
appveyor.yml,main分支自动发布到 NuGet。
- Fork 并创建特性分支:
git checkout -b feature/xxx - 补充或维护对应模块的单元测试。
- 确保
dotnet test全部通过。 - 提交 PR。
