Inkslab 1.2.18
dotnet add package Inkslab --version 1.2.18
NuGet\Install-Package Inkslab -Version 1.2.18
<PackageReference Include="Inkslab" Version="1.2.18" />
<PackageVersion Include="Inkslab" Version="1.2.18" />
<PackageReference Include="Inkslab" />
paket add Inkslab --version 1.2.18
#r "nuget: Inkslab, 1.2.18"
#:package Inkslab@1.2.18
#addin nuget:?package=Inkslab&version=1.2.18
#tool nuget:?package=Inkslab&version=1.2.18
"Inkslab"是什么?
Inkslab 是一套简单、高效的轻量级框架,专注于现代化 C# 开发体验。框架采用模块化设计,提供统一的 API 接口,涵盖了对象映射、配置读取、序列化、依赖注入等核心功能。
🎯 核心特性
- 统一API设计 - 所有模块遵循一致的设计原则和API风格
- 语法糖扩展 - 基于扩展方法的语法糖,提升开发效率
- 模块化架构 - 按需引用,最小化依赖
- 自动启动机制 -
XStartup自动发现和注册组件 - 多框架支持 - 支持 .NET Framework 4.6.1+、.NET Standard 2.1、.NET 6.0+
🚀 快速入门
安装
PM> Install-Package Inkslab
基础配置
using Inkslab;
// 框架自动启动(推荐)
using (var startup = new XStartup())
{
startup.DoStartup();
}
📦 NuGet 包
| Package | NuGet | Downloads | 描述 |
|---|---|---|---|
| Inkslab | 核心框架 | ||
| Inkslab.Config | 配置文件读取 | ||
| Inkslab.Json | JSON 序列化 | ||
| Inkslab.Map | 对象映射 | ||
| Inkslab.DI | 依赖注入扩展 | ||
| Inkslab.Net | HTTP 请求组件 |
🏗️ 核心技术架构
1. 扩展方法体系
Inkslab 基于 C# 扩展方法构建了一套完整的语法糖体系,位于 src/Inkslab/Extentions/ 目录:
字符串扩展 (StringExtensions)
// 命名规范转换
string camelCase = "UserName".ToCamelCase(); // → "userName"
string snakeCase = "UserName".ToSnakeCase(); // → "user_name"
string pascalCase = "user_name".ToPascalCase(); // → "UserName"
string kebabCase = "UserName".ToKebabCase(); // → "user-name"
// 统一命名转换API
string result = "UserName".ToNamingCase(NamingType.SnakeCase); // → "user_name"
// 配置读取语法糖
string dbConnection = "ConnectionStrings:Default".Config<string>();
var appSettings = "AppSettings".Config<AppConfig>();
集合扩展 (IEnumerableExtentions)
/// <summary>
/// 内容对齐。
/// </summary>
public void AlignTest()
{
var array1 = new List<int> { 1, 2, 3, 4, 5, 6, 7 };
var array2 = new List<int> { 4, 5, 1, 2, 3, 6, 7 };
//? 将 array2 按照 array1 的集合排序。
var array3 = array2
.AlignOverall(array1)
.ToList();
//? 比较两个集合相同下标位,值是否相同。
array3.ZipEach(array1, Assert.Equal);
}
/// <summary>
/// 内容遍历。
/// </summary>
public void JoinEachTest()
{
var array1 = new List<int> { 1, 2, 3, 4, 5, 6, 7 };
var array2 = new List<DistinctA>();
var r = new Random();
for (int i = 0, len = 50; i < len; i++)
{
array2.Add(new DistinctA
{
Id = r.Next(len),
Name = i.ToString(),
Date = DateTime.Now
});
}
//? 与 Join 逻辑相同,但不需要返回新的集合。
array1.JoinEach(array2, x => x, y => y.Id, (x, y) =>
{
Assert.Equal(x, y.Id);
});
}
加密扩展 (CryptoExtensions)
// 常用哈希算法
string md5 = "password".Md5();
string encrypt = "data".Encrypt("Test@*$!", CryptoKind.DES); // 加密
string decrypt = "data".Decrypt("Test@*$!", CryptoKind.DES); // 解密
日期时间扩展 (DateTimeExtensions)
自动根据提供时间是Utc / Local 自动处理一周的第一天和最后一天。
- Utc:周日为一周的第一天;周六为一周的最后一天。
- Local:周一为一周的第一天;周日为一周的最后一天。
2. 序列化框架
JSON 序列化 (基于 Newtonsoft.Json)
核心实现:DefaultJsonHelper
// 基础用法
string json = JsonHelper.ToJson(obj);
T result = JsonHelper.Json<T>(json);
// 命名规范支持
string json = JsonHelper.ToJson(obj, NamingType.CamelCase);
var result = JsonHelper.Json<User>(json, NamingType.SnakeCase);
// 格式化输出
string prettyJson = JsonHelper.ToJson(obj, indented: true);
自定义JSON序列化器
public class CustomJsonHelper : IJsonHelper
{
public string ToJson<T>(T jsonObj, NamingType namingType = NamingType.Normal, bool indented = false)
{
// 自定义序列化逻辑
var settings = new JsonSerializerSettings();
// 根据命名规范配置
switch (namingType)
{
case NamingType.CamelCase:
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
break;
case NamingType.SnakeCase:
settings.ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
};
break;
}
return JsonConvert.SerializeObject(jsonObj, indented ? Formatting.Indented : Formatting.None, settings);
}
public T Json<T>(string json, NamingType namingType = NamingType.Normal)
{
// 自定义反序列化逻辑
}
}
// 注册自定义实现
SingletonPools.TryAdd<IJsonHelper, CustomJsonHelper>();
3. 语法糖适配器 (AdapterSugar)
Inkslab 框架通过 AdapterSugar<T> 实现了自动化的语法糖适配机制,极大提升了扩展性和运行时性能。其核心流程如下:
1. 类型与成员信息初始化
- 自动获取泛型参数 T 及正则相关类型(如 Match、Group、Capture 等)的反射信息。
- 构建表达式树所需的参数表达式。
2. 方法发现与遍历
- 自动发现 T 类型下所有公开实例方法。
- 仅处理参数数量大于0且返回类型为 string 的方法。
3. 参数分析与表达式构建
- 支持参数类型:Match、GroupCollection、Group、CaptureCollection、Capture、string、bool。
- 根据参数类型,自动生成变量声明、赋值、条件判断及参数列表。
- 不支持类型将抛出异常,确保类型安全。
4. 条件与特性处理
- 支持 MatchAttribute 指定正则分组名。
- 支持 MismatchAttribute 补充不匹配条件。
- 汇总所有条件表达式,生成最终的匹配条件。
5. 表达式树编译
- 条件表达式编译为 Func<Match, bool>,用于判断当前正则匹配是否适用该方法。
- 方法调用表达式编译为 Func<T, Match, string>,用于执行实际转换逻辑。
6. 适配器缓存
- 每个方法生成一个适配器(包含条件判断与转换逻辑),自动缓存到静态列表,供后续格式化调用时高效匹配和执行。
public abstract class AdapterSugar<T> : ISugar where T : AdapterSugar<T>, ISugar
{
// 适配器模式实现
private class Adapter
{
public Func<Match, bool> CanConvert { get; set; }
public Func<T, Match, string> Convert { get; set; }
}
// 撤销操作
public bool Undo { get; private set; }
// 格式化方法
public string Format(Match match);
}
自定义语法糖示例
public class StringSugar : AdapterSugar<StringSugar>
{
private readonly object _source;
private readonly DefaultSettings _settings;
private readonly SyntaxPool _syntaxPool;
public StringSugar(object source, DefaultSettings settings, SyntaxPool syntaxPool)
{
_source = source ?? throw new ArgumentNullException(nameof(source));
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
_syntaxPool = syntaxPool ?? throw new ArgumentNullException(nameof(syntaxPool));
}
[Mismatch("token")] //? 不匹配 token。
public string Single(string name, string format) => _syntaxPool.GetValue(this, _source, _settings, name, format);
[Mismatch("token")] //? 不匹配 token。
public string Single(string name) => _syntaxPool.GetValue(this, _source, _settings, name);
public string Combination(string pre, string token, string name, string format) => _syntaxPool.GetValue(this, _source, _settings, pre, token, name, format);
public string Combination(string pre, string token, string name) => _syntaxPool.GetValue(this, _source, _settings, pre, token, name);
}
4. 单例池管理 (SingletonPools)
// 注册单例
SingletonPools.TryAdd<IService, ServiceImpl>();
SingletonPools.TryAdd(new ServiceInstance());
// 获取单例
var service = SingletonPools.Singleton<IService>();
💡 核心功能详解
配置管理
// 强类型配置
public class DatabaseConfig
{
public string ConnectionString { get; set; }
public int Timeout { get; set; }
}
var dbConfig = "Database".Config<DatabaseConfig>();
// 配置监听(热更新)
var options = "Database".Options<DatabaseConfig>();
// options.Value 会随配置文件变化自动更新
对象映射
// 基础映射
var dto = Mapper.Map<UserDto>(user);
主键生成
// 雪花算法ID生成
long id = KeyGen.Id();
Key newKey = KeyGen.New();
// 自定义机房和机器号
SingletonPools.TryAdd(new KeyOptions(workerId: 1, datacenterId: 1));
命名规范转换
基于 NamingType 枚举的统一命名处理:
public enum NamingType
{
Normal = 0, // 原样输出
CamelCase = 1, // 驼峰:userName
SnakeCase = 2, // 蛇形:user_name
PascalCase = 3, // 帕斯卡:UserName
KebabCase = 4 // 短横线:user-name
}
// 使用示例
string result = "UserName".ToNamingCase(NamingType.SnakeCase);
🎓 高级应用指南
1. 自定义启动器
实现 IStartup 接口创建自定义启动器:
public class CustomStartup : IStartup
{
public int Code => 999; // 启动代码(用于排序)
public int Weight => 1; // 权重
public void Startup()
{
// 自定义初始化逻辑
SingletonPools.TryAdd<ICustomService, CustomServiceImpl>();
// 注册语法糖
RegisterCustomSyntaxSugar();
// 配置全局设置
ConfigureGlobalSettings();
}
}
2. 扩展方法最佳实践
#pragma warning disable IDE0130 // 命名空间与文件夹结构不匹配
namespace System // 扩展到系统命名空间,全局可用
#pragma warning restore IDE0130
{
public static class CustomExtensions
{
/// <summary>
/// 安全的字符串截取
/// </summary>
public static string SafeSubstring(this string source, int startIndex, int length)
{
if (string.IsNullOrEmpty(source) || startIndex >= source.Length)
return string.Empty;
return source.Substring(startIndex, Math.Min(length, source.Length - startIndex));
}
/// <summary>
/// 条件执行扩展
/// </summary>
public static T If<T>(this T source, bool condition, Func<T, T> action)
{
return condition ? action(source) : source;
}
}
}
3. 高性能序列化配置
public class HighPerformanceJsonHelper : IJsonHelper
{
private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
// 性能优化配置
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore,
// 类型处理
TypeNameHandling = TypeNameHandling.None,
// 错误处理
Error = (sender, args) =>
{
// 记录序列化错误但不中断处理
args.ErrorContext.Handled = true;
}
};
public string ToJson<T>(T jsonObj, NamingType namingType = NamingType.Normal, bool indented = false)
{
var settings = Settings.Clone();
settings.ContractResolver = GetContractResolver(namingType);
settings.Formatting = indented ? Formatting.Indented : Formatting.None;
return JsonConvert.SerializeObject(jsonObj, settings);
}
private static IContractResolver GetContractResolver(NamingType namingType)
{
// 缓存 ContractResolver 实例以提升性能
return namingType switch
{
NamingType.CamelCase => CachedResolvers.CamelCase,
NamingType.SnakeCase => CachedResolvers.SnakeCase,
NamingType.PascalCase => CachedResolvers.PascalCase,
NamingType.KebabCase => CachedResolvers.KebabCase,
_ => CachedResolvers.Default
};
}
private static class CachedResolvers
{
public static readonly IContractResolver Default = new DefaultContractResolver();
public static readonly IContractResolver CamelCase = new CamelCasePropertyNamesContractResolver();
public static readonly IContractResolver SnakeCase = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
};
// ... 其他缓存的解析器
}
}
4. 模块化架构设计
// 模块接口定义
public interface IModule
{
string Name { get; }
Version Version { get; }
void Initialize();
void Dispose();
}
// 模块管理器
public class ModuleManager
{
private readonly List<IModule> _modules = new();
public void LoadModule<T>() where T : IModule, new()
{
var module = new T();
module.Initialize();
_modules.Add(module);
}
public void LoadModules(Assembly assembly)
{
var moduleTypes = assembly.GetTypes()
.Where(t => typeof(IModule).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
foreach (var type in moduleTypes)
{
var module = (IModule)Activator.CreateInstance(type);
module.Initialize();
_modules.Add(module);
}
}
}
// 在启动器中使用
public class ModularStartup : IStartup
{
public int Code => 100;
public int Weight => 1;
public void Startup()
{
var moduleManager = new ModuleManager();
// 加载核心模块
moduleManager.LoadModule<ConfigModule>();
moduleManager.LoadModule<JsonModule>();
moduleManager.LoadModule<MappingModule>();
// 自动发现并加载模块
var assemblies = AssemblyFinder.FindAssemblies("*.Module.dll");
foreach (var assembly in assemblies)
{
moduleManager.LoadModules(assembly);
}
SingletonPools.TryAdd<ModuleManager>(moduleManager);
}
}
5. 性能监控和诊断
public static class PerformanceExtensions
{
public static T WithTiming<T>(this Func<T> func, Action<TimeSpan> onCompleted)
{
var stopwatch = Stopwatch.StartNew();
try
{
return func();
}
finally
{
stopwatch.Stop();
onCompleted(stopwatch.Elapsed);
}
}
public static async Task<T> WithTimingAsync<T>(this Func<Task<T>> func, Action<TimeSpan> onCompleted)
{
var stopwatch = Stopwatch.StartNew();
try
{
return await func();
}
finally
{
stopwatch.Stop();
onCompleted(stopwatch.Elapsed);
}
}
}
// 使用示例
var result = (() => ExpensiveOperation()).WithTiming(elapsed =>
{
if (elapsed.TotalMilliseconds > 1000)
{
Logger.LogWarning($"Slow operation detected: {elapsed.TotalMilliseconds}ms");
}
});
🔧 测试和调试
框架提供了完整的单元测试,位于 tests/ 目录:
Inkslab.Tests- 核心功能测试Inkslab.Json.Tests- JSON序列化测试Inkslab.Config.Tests- 配置读取测试Inkslab.Map.Tests- 对象映射测试
示例测试用例
参考 StringExtensionsTests 了解如何编写测试:
[Theory]
[InlineData("namingCase", NamingType.Normal, "namingCase")]
[InlineData("NamingCase", NamingType.CamelCase, "namingCase")]
[InlineData("naming_case", NamingType.PascalCase, "NamingCase")]
[InlineData("UserName", NamingType.SnakeCase, "user_name")]
public void NamingConversionTest(string input, NamingType namingType, string expected)
{
var result = input.ToNamingCase(namingType);
Assert.Equal(expected, result);
}
📈 性能建议
- 合理使用单例池 - 避免频繁创建重型对象
- 缓存序列化配置 - JsonSerializerSettings 等配置对象应该缓存
- 批量操作 - 使用框架提供的批量扩展方法
- 异步优先 - 在 I/O 密集型操作中优先使用异步方法
- 监控内存使用 - 定期检查大对象和集合的内存占用
🤝 贡献指南
- Fork 项目
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 打开 Pull Request
📝 许可证
本项目基于 MIT 许可证 - 查看 LICENSE 文件了解详情。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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 was computed. 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. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| .NET Framework | net461 is compatible. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.1
- No dependencies.
-
.NETStandard 2.1
- No dependencies.
-
net6.0
- No dependencies.
NuGet packages (6)
Showing the top 5 NuGet packages that depend on Inkslab:
| Package | Downloads |
|---|---|
|
Inkslab.Map
A convention-based object-object mapper. |
|
|
Inkslab.DI
An automated dependency injection extension. |
|
|
Inkslab.Net
A network communications assistant. |
|
|
Inkslab.Config
The configured reader. |
|
|
Inkslab.Json
A high-performance JSON framework. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 1.2.18 | 1,844 | 10/9/2025 | |
| 1.2.17 | 371 | 8/15/2025 | |
| 1.2.16 | 399 | 6/7/2025 | |
| 1.2.14 | 3,674 | 11/22/2024 | |
| 1.2.13 | 2,293 | 9/10/2024 | |
| 1.2.12 | 419 | 9/10/2024 | |
| 1.2.11 | 486 | 8/4/2024 | |
| 1.2.10 | 336 | 7/29/2024 | |
| 1.2.9 | 335 | 7/29/2024 | |
| 1.2.8.5 | 3,672 | 5/15/2024 | |
| 1.2.8 | 3,942 | 3/26/2024 | |
| 1.2.7 | 511 | 3/1/2024 | |
| 1.2.5 | 854 | 1/2/2024 | |
| 1.2.4.1 | 580 | 12/20/2023 | |
| 1.2.4 | 587 | 12/12/2023 | |
| 1.2.3 | 460 | 12/12/2023 | |
| 1.2.2 | 447 | 12/12/2023 | |
| 1.2.1.15 | 595 | 11/22/2023 | |
| 1.2.1.14 | 809 | 11/8/2023 | |
| 1.2.1.13 | 528 | 11/3/2023 | |
| 1.2.1.12 | 536 | 11/1/2023 | |
| 1.2.1.11 | 504 | 10/25/2023 | |
| 1.2.1.10 | 460 | 10/24/2023 | |
| 1.2.1.9 | 476 | 10/22/2023 | |
| 1.2.1.8 | 468 | 10/16/2023 | |
| 1.2.1.7 | 472 | 10/12/2023 | |
| 1.2.1.6 | 700 | 10/9/2023 | |
| 1.2.1.4 | 1,006 | 7/14/2023 | |
| 1.2.1.3 | 574 | 7/14/2023 | |
| 1.2.1.1 | 612 | 7/12/2023 | |
| 1.2.1 | 550 | 7/10/2023 | |
| 1.2.0 | 567 | 7/9/2023 | |
| 1.1.0 | 566 | 7/9/2023 | |
| 1.0.2.9 | 837 | 4/21/2023 | |
| 1.0.2.8 | 693 | 4/21/2023 | |
| 1.0.2.7 | 850 | 3/30/2023 | |
| 1.0.2.5 | 1,155 | 2/23/2023 | |
| 1.0.2.1 | 1,210 | 2/7/2023 | |
| 1.0.2 | 1,155 | 2/3/2023 | |
| 1.0.1 | 1,359 | 12/20/2022 | |
| 1.0.0 | 1,195 | 12/13/2022 |