{"id":25772805,"url":"https://github.com/tinylit/inkslab","last_synced_at":"2025-06-11T15:39:33.105Z","repository":{"id":64711604,"uuid":"515955026","full_name":"tinylit/inkslab","owner":"tinylit","description":"【架构体系】笔墨纸砚，笔是灵魂、墨是自研、纸是平台、砚是辅助和支持。","archived":false,"fork":false,"pushed_at":"2025-06-05T06:48:22.000Z","size":694,"stargazers_count":12,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-05T07:56:58.736Z","etag":null,"topics":["dependency-injection","high-performance","json","lightweight","map","xml"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tinylit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-07-20T11:31:57.000Z","updated_at":"2025-05-28T07:19:17.000Z","dependencies_parsed_at":"2023-12-11T14:36:48.821Z","dependency_job_id":"b3e85484-9d5d-4922-bec1-89ba9f301b9b","html_url":"https://github.com/tinylit/inkslab","commit_stats":{"total_commits":47,"total_committers":2,"mean_commits":23.5,"dds":"0.021276595744680882","last_synced_commit":"98acb040607ea6b6383201ddf5af1bc961f27e6d"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tinylit/inkslab","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinylit%2Finkslab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinylit%2Finkslab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinylit%2Finkslab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinylit%2Finkslab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tinylit","download_url":"https://codeload.github.com/tinylit/inkslab/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinylit%2Finkslab/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259290705,"owners_count":22835275,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency-injection","high-performance","json","lightweight","map","xml"],"created_at":"2025-02-27T04:19:47.015Z","updated_at":"2025-06-11T15:39:33.066Z","avatar_url":"https://github.com/tinylit.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Inkslab](inkslab.jpg 'Logo')\n\n![GitHub](https://img.shields.io/github/license/tinylit/inkslab.svg)\n![language](https://img.shields.io/github/languages/top/tinylit/inkslab.svg)\n![codeSize](https://img.shields.io/github/languages/code-size/tinylit/inkslab.svg)\n![AppVeyor](https://img.shields.io/appveyor/build/tinylit/inkslab)\n![AppVeyor tests](https://img.shields.io/appveyor/tests/tinylit/inkslab)\n[![GitHub issues](https://img.shields.io/github/issues-raw/tinylit/inkslab)](../../issues)\n\n### “Inkslab”是什么？\n\nInkslab 是一套简单、高效的轻量级框架（涵盖了对象映射、配置读取、Xml/Json序列化和反序列化、以及自动/定制化依赖注入）。\n\n### 如何安装？\nFirst, [install NuGet](http://docs.nuget.org/docs/start-here/installing-nuget). Then, install [Inkslab](https://www.nuget.org/packages/inkslab/) from the package manager console: \n\n```\nPM\u003e Install-Package Inkslab\n```\n### 引包即用？\n\n* 引包即用是指，安装 `NuGet` 包后，自动注入配置信息。\n* 在启动方法中添加如下代码即可：\n``` csharp\nusing (var startup = new XStartup())\n{\n    startup.DoStartup();\n}\n```\n\nNuGet 包\n--------\n\n| Package | NuGet | Downloads | Jane Says \u003ckbd\u003eMarkdown\u003c/kbd\u003e |\n| ------- | ----- | --------- | --------- |\n| Inkslab | [![Inkslab](https://img.shields.io/nuget/v/inkslab.svg)](https://www.nuget.org/packages/inkslab/) | ![Nuget](https://img.shields.io/nuget/dt/Inkslab) | Core universal design. |\n| Inkslab.Map | [![Inkslab.Map](https://img.shields.io/nuget/v/inkslab.map.svg)](https://www.nuget.org/packages/inkslab.map/) | ![Nuget](https://img.shields.io/nuget/dt/Inkslab.Map) | [Type conversion, cloning, mapping.](./Inkslab.Map.md) |\n| Inkslab.Config | [![Inkslab.Config](https://img.shields.io/nuget/v/inkslab.config.svg)](https://www.nuget.org/packages/inkslab.config/) | ![Nuget](https://img.shields.io/nuget/dt/Inkslab.Config) | [Read configuration file.](./Inkslab.Config.md) |\n| Inkslab.Json | [![Inkslab.Json](https://img.shields.io/nuget/v/inkslab.json.svg)](https://www.nuget.org/packages/inkslab.json/) | ![Nuget](https://img.shields.io/nuget/dt/Inkslab.Json) | [JSON read and write processing.](./Inkslab.Json.md) |\n| Inkslab.Net | [![Inkslab.Net](https://img.shields.io/nuget/v/inkslab.net.svg)](https://www.nuget.org/packages/inkslab.net/) | ![Nuget](https://img.shields.io/nuget/dt/Inkslab.Net) | [Request component of HTTP/HTTPS.](./Inkslab.Net.md) |\n\n### 内置功能。\n  * Xml 系列化和反序列化助手。\n    - 使用方式。\n    ```c#\n    /// \u003csummary\u003e\n    /// 序列化实体。\n    /// \u003c/summary\u003e\n    [XmlRoot(\"xml\")]\n    public class XmlA\n    {\n        /// \u003csummary\u003e\n        /// 忽略字段。\n        /// \u003c/summary\u003e\n        [Ignore] //? 忽略字段。\n        public int A1 { get; set; } = 100;\n\n        /// \u003csummary\u003e\n        /// 生成 \u003c![CDATA[{value}]]\u003e\n        /// \u003c/summary\u003e\n        public CData A2 { get; set; }\n\n        /// \u003csummary\u003e\n        /// \u003cinheritdoc/\u003e\n        /// \u003c/summary\u003e\n        public string A3 { get; set; }\n\n        /// \u003csummary\u003e\n        /// \u003cinheritdoc/\u003e\n        /// \u003c/summary\u003e\n        public DateTime A4 { get; set; }\n    }\n    /// \u003csummary\u003e\n    /// 反序列化实体。\n    /// \u003c/summary\u003e\n    [XmlRoot(\"xml\")]\n    public class XmlB\n    {\n        /// \u003csummary\u003e\n        /// 忽略字段。\n        /// \u003c/summary\u003e\n        [Ignore] //? 忽略字段。\n        public int A1 { get; set; } = 100;\n        /// \u003csummary\u003e\n        /// \u003cinheritdoc/\u003e\n        /// \u003c/summary\u003e\n        public string A2 { get; set; }\n        /// \u003csummary\u003e\n        /// \u003cinheritdoc/\u003e\n        /// \u003c/summary\u003e\n        public string A3 { get; set; }\n        /// \u003csummary\u003e\n        /// \u003cinheritdoc/\u003e\n        /// \u003c/summary\u003e\n        public DateTime A4 { get; set; }\n    }\n    ```\n     * 序列化。\n     ```c#\n      XmlA x = new XmlA\n      {\n          A1 = 200,\n          A2 = \"测试CData节点\",\n          A3 = \"普通节点\",\n          A4 = DateTime.Now\n      };\n\n      string xml = XmlHelper.XmlSerialize(x);\n     ```\n    * 反序列化。\n    ```c#\n     string xml =\"\u003c?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?\u003e\u003cxml xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\"\u003e\u003cA2\u003e\u003c![CDATA[测试CData节点]]\u003e\u003c/A2\u003e\u003cA3\u003e普通节点\u003c/A3\u003e\u003cA4\u003e2022-12-03T14:53:29.1218173+08:00\u003c/A4\u003e\u003c/xml\u003e\";\n\n     XmlB y = XmlHelper.XmlDeserialize\u003cXmlB\u003e(xml);\n    ```\n  * 自定义程序集查找器。\n    - 自定义【IDirectory】。\n        ```c#\n            public class CustomDirectory : IDirectory\n            {\n                public string[] GetFiles(string path, string searchPattern) =\u003e Directory.GetFiles(path, searchPattern);\n            }\n        ```\n    - 注入到单列池中。\n        ```c#\n            SingletonPools.TryAdd\u003cIDirectory, CustomDirectory\u003e();\n        ```\n\n  * 配置文件助手。\n    - 使用方式：\n\n      * 普通类型。\n\n        ```c#\n        var value = \"config-key\".Config\u003cstring\u003e(); // 返回结果字符串。\n        ```  \n\n      * 监听类型。\n\n        ```c#  \n        var options = \"config-key\".Options\u003cstring\u003e(); // 返回IOptions\u0026lt;string\u0026gt;配置。\n        var value = options.Value; // 配置文件发生变化时，“options.Value”会被更新。\n        ```\n    - 默认实现，\n      ```\n      PM\u003e Install-Package Inkslab.Config\n      ```\n    - 如需自定义，请参考 [Inkslab.Config](Inkslab.Config.md 'Logo') 文稿。\n  * Json 序列化和反序列化助手。\n    - 使用方式：\n\n      * 序列化。\n\n        ```c#\n        string json = JsonHelper.ToJson(new { Id = KeyGen.Id(), Timestamp = DateTime.Now });\n        ```\n\n      * 反序列化。\n\n        ```c#\n          /// \u003csummary\u003e\n          /// 序列化类型。\n          /// \u003c/summary\u003e\n          public class A\n          {\n              /// \u003csummary\u003e\n              /// 不序列化这个属性。\n              /// \u003c/summary\u003e\n              [Ignore]\n              public int A1 { get; set; } = 100;\n\n              /// \u003csummary\u003e\n              /// \u003csee cref=\"A2\"/\u003e\n              /// \u003c/summary\u003e\n              public int A2 { get; set; }\n\n              /// \u003csummary\u003e\n              /// \u003csee cref=\"A3\"/\u003e\n              /// \u003c/summary\u003e\n              public string A3 { get; set; } = string.Empty;\n\n              /// \u003csummary\u003e\n              /// \u003csee cref=\"A4\"/\u003e\n              /// \u003c/summary\u003e\n              public DateTime A4 { get; set; }\n          }\n\n          string json = \"{\\\"A2\\\":100,\\\"A3\\\":\\\"A3\\\",\\\"A4\\\":\\\"2022-12-03 14:17:55.7425309+08:00\\\"}\"; // JSON 字符串。\n          A a = JsonHelper.Json\u003cA\u003e(json); // 转换实体、匿名类型请参考重载方法。\n        ```\n    - 默认实现，\n      ```\n      PM\u003e Install-Package Inkslab.Json\n      ```\n    - 如需自定义，请参考 [Inkslab.Json](Inkslab.Json.md 'Logo') 文稿。\n\n  * 对象映射。\n    - 使用方式。\n    ```c#\n     FooDto fooDto = Mapper.Map\u003cFooDto\u003e(foo);\n     BarDto barDto = Mapper.Map\u003cBarDto\u003e(bar);\n    ```\n    - 默认实现，\n       ```\n       PM\u003e Install-Package Inkslab.Map\n       ```\n    - 如需自定义或了解**高级语法**，请参考 [Inkslab.Map](Inkslab.Map.md 'Logo') 文稿。\n  * 主键生成器。\n    - 使用方式。\n    ```c#\n    long id = KeyGen.Id();\n    ```\n    - 默认实现：雪花算法。 \n    - 设置机房和机号。\n    ```c#\n    SingletonPools.TryAdd(new KeyOptions(workerId, datacenterId));\n    ```\n    - 自定义主键生成器。\n      - 实现接口。\n      ```c#\n      /// \u003csummary\u003e\n      /// KeyGen 创建器。\n      /// \u003c/summary\u003e\n      public interface IKeyGenFactory\n      {\n          /// \u003csummary\u003e\n          /// 创建。\n          /// \u003c/summary\u003e\n          /// \u003creturns\u003e\u003c/returns\u003e\n          IKeyGen Create();\n      }\n      ```\n      - 注入实现。\n      ```c#\n      SingletonPools.TryAdd\u003cIMapper, CustomMapper\u003e();\n      ```\n      - 正常使用。\n\n### 单例。\n\n* 作为单例基类。\n\n  ```c#\n  public class ASingleton : Singleton\u003cASingleton\u003e {\n      private ASingleton(){ }\n  }\n  \n  ASingleton singleton = ASingleton.Instance;\n  ```\n\n* 作为单例使用。\n\n  ```c#\n  public class BSingleton {   \n  }\n  \n  BSingleton singleton = Singleton\u003cBSingleton\u003e.Instance\n  ```\n\n* 绝对单例。\n\n  ```c#\n  public class CSingleton : Singleton\u003cCSingleton\u003e {\n      private CSingleton(){ }\n  }\n  \n  CSingleton singleton1 = CSingleton.Instance;\n  CSingleton singleton2 = Singleton\u003cCSingleton\u003e.Instance; // 与“singleton1”是同一实例。\n  ```\n\n### 单例池。\n\n* TryAdd：添加单例实现。\n\n* Singleton：获取单例。\n\n* 单例实现：\n\n  - 单例实现（一）。\n\n    - 添加默认支持的单例实现。\n\n    ```c#\n    SingletonPools.TryAdd\u003cA,B\u003e(); //=\u003e true.\n    ```\n\n    - 在未使用A的实现前，可以刷新单例实现支持。\n\n    ```c#\n    SingletonPools.TryAdd\u003cA,C\u003e(); //=\u003e true;\n    SingletonPools.TryAdd\u003cA\u003e(new C()); //=\u003e true;\n    ```\n\n  - 单例实现（二）。\n\n    - 添加实例或工厂支持的单例实现。\n\n    ```c#\n    SingletonPools.TryAdd\u003cA\u003e(new B()); //=\u003e true.\n    ```\n\n    - 在未使用A的实现前，可以被实例或工厂刷新单例实现支持，默认支持方式不被生效。\n\n    ```c#\n    SingletonPools.TryAdd\u003cA,C\u003e(); //=\u003e false;\n    SingletonPools.TryAdd\u003cA\u003e(new C()); //=\u003e true;\n    ```\n\n* 单例使用：\n\n  - 单例使用（一）。\n\n    ```c#\n    A a = SingletonPools.Singleton\u003cA\u003e();\n    ```\n\n    未提前注入单例实现，会直接抛出`NotImplementedException`异常。\n\n  - 单例使用（二）。\n\n    ```c#\n    A a = SingletonPools.Singleton\u003cA,B\u003e();\n    ```\n\n    未提前注入单例实现，会尝试创建`B`实例。\n\n- 说明：\n\n  - TryAdd\u0026lt;T\u0026gt;：使用实例时，使用【公共/非公共】无参构造函数创建实例。\n\n  - TryAdd\u0026lt;T1,T2\u0026gt;：使用实例时，尽量使用参数更多且被支持的公共构造函数创建实例。\n\n    ```c#\n    public class A {\n    }\n    public class B {\n        private readonly A a;\n        public B() : this(new A()){ }\n        Public B(A a){ this.a = a ?? throw new ArgumentNullException(nameof(a)); }\n    }\n    ```\n\n    使用单例时，未注入A的单例实现，使用无参构造函数生成实例。\n\n    使用单例时，已注入A的单例实现，使用参数`A`的造函数生成实例。\n\n### 命名规范。\n\n* 命名方式。\n\n  ```c#\n  /// \u003csummary\u003e 命名规范。 \u003c/summary\u003e\n  public enum NamingType\n  {\n      /// \u003csummary\u003e 默认命名(原样/业务自定义)。 \u003c/summary\u003e\n      Normal = 0,\n  \n      /// \u003csummary\u003e 驼峰命名,如：userName。 \u003c/summary\u003e\n      CamelCase = 1,\n  \n      /// \u003csummary\u003e 蛇形命名,如：user_name，注：反序列化时也需要指明。 \u003c/summary\u003e\n      SnakeCase = 2,\n  \n      /// \u003csummary\u003e 帕斯卡命名,如：UserName。 \u003c/summary\u003e\n      PascalCase = 3,\n  \n      /// \u003csummary\u003e短横线命名,如：user-name。\u003c/summary\u003e\n      KebabCase = 4\n  }\n  ```\n\n### 命名转换（三种命名可以相互转换）。\n\n* 指定命名方式。\n\n  ```c#\n  string named = \"name\".ToNamingCase(NamingType.CamelCase);\n  ```\n\n* 特定命名方式。\n\n  - 帕斯卡命名（又称大驼峰）。\n\n    ```c#\n    string named = \"user_name\".ToPascalCase(); // UserName\n    ```\n\n  - 驼峰命名。\n\n    ```c#\n    string named = \"user_name\".ToCamelCase(); // userName\n    ```\n\n  - 蛇形命名。\n\n    ```c#\n    string named = \"user_name\".ToSnakeCase(); // user_name\n    ```\n  - 短横线命名\n    ```c#\n    string named = \"user_name\".ToKebabCase(); // user-name\n    ```\n\n### 字符串语法糖。\n\n```c#\nstring value = \"${a + b}\".PropSugar(new { A = 1, B = 2 }); //=\u003e value = \"3\"。\n```\n\n* 语法说明：\n\n  - 空运算符：A ? B、A ?? B\n\n    当A为`null`时，返回B，否则返回A。\n\n  - 合并运算符：A + B\n\n    当A和B可以参与运算时，返回运算结果。否则转成字符串拼接。\n\n  - 试空合并运算符：A ?+ B\n\n    当A为`null`时，返回`null`，否则按照【合并运算符】计算A+B的结果。\n  \n  -  属性后代：A.B 或 A.B.C ...\n\n标星历程图。\n\n[![Stargazers over time](https://starchart.cc/tinylit/inkslab.svg)](https://starchart.cc/tinylit/inkslab)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinylit%2Finkslab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftinylit%2Finkslab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinylit%2Finkslab/lists"}