解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
|
# NewLife.Core 架构设计
> 版本:v12 | 日期:2026-10-07 | 从代码结构逆向整理
本文档描述 NewLife.Core 核心库的架构设计。需求定义见[需求文档](/NewLife/X/Blob/v12.0.2026.1024/Doc/需求文档.md),功能追踪见[功能清单](/NewLife/X/Blob/v12.0.2026.1024/Doc/功能清单.md)。
## 1. 项目分层
NewLife.Core 采用**单项目 + 目录命名空间**的轻量分层架构,不拆分多项目(符合 NewLife 从两层起步的理念)。
```
NewLife.Core/
├── Common/ # 根命名空间 NewLife.*(基础类型)
├── Extension/ # NewLife.* 扩展方法
├── Event/ # NewLife.* 事件与弱引用委托
├── Exceptions/ # NewLife.* 异常类型
├── Stub/ # 兼容性填充(低版本 .NET 缺失类型)
├── Collections/ # NewLife.Collections 集合与池化
├── Caching/ # NewLife.Caching 缓存系统
├── Configuration/ # NewLife.Configuration 配置系统
├── Data/ # NewLife.Data 数据结构与数据管道
├── Log/ # NewLife.Log 日志与追踪
├── Model/ # NewLife.Model 应用框架
├── Reflection/ # NewLife.Reflection 反射扩展
├── Net/ # NewLife.Net 网络库
├── Http/ # NewLife.Http HTTP 组件
├── Remoting/ # NewLife.Remoting RPC 框架
├── Serialization/ # NewLife.Serialization 序列化
│ ├── Json/ # JSON 序列化子模块
│ └── Xml/ # XML 序列化子模块
├── Security/ # NewLife.Security 安全加密
├── Threading/ # NewLife.Threading 定时调度
├── Messaging/ # NewLife.Messaging 消息、帧泵与编解码器
├── Web/ # NewLife.Web Web 工具
├── IO/ # NewLife.IO 文件与存储
├── Compression/ # NewLife.Compression 压缩归档
├── Algorithms/ # NewLife.Algorithms 数据算法
├── Buffers/ # NewLife.Buffers 高性能缓冲区
├── Xml/ # NewLife.Xml XML 配置
├── Windows/ # NewLife.Windows Windows 特定
├── Setting.cs # 核心配置 Setting
└── NewLife.Core.csproj # 多目标框架:net45~net10.0
```
## 2. 模块架构
### 2.1 基础扩展(M1)
层内无依赖,被所有上层模块依赖。
核心组件:`Utility`(类型转换)、`StringHelper`(字符串)、`DisposeBase`(资源释放)、`Runtime`(运行时)、`TimeProvider`(时间抽象)、`IDictionarySource`(字典数据源)、`MachineInfo`(机器信息)。
### 2.2 日志与追踪(M2)
```
ILog (接口)
├── TextFileLog # 文件日志
├── ConsoleLog # 控制台日志
├── NetworkLog # 网络日志(UDP)
├── CompositeLog # 组合日志
├── LevelLog # 级别过滤包装
└── ActionLog # 回调日志
ITracer (接口)
└── DefaultTracer # 集成星尘平台 APM
XTrace # 全局静态日志入口
Logger # 日志工厂
PerfCounter # 性能计数器
LogEventListener # ETW 日志监听
```
### 2.3 定时调度(M3)
```
TimerX # 高精度定时器(支持 Cron 和异步回调)
Cron # Cron 表达式解析(秒级 7 域)
TimerScheduler # 定时任务调度器
ThreadPoolX # 线程池扩展包装器
```
### 2.4 序列化(M4)
```
IFormatterX (接口)
├── Json # JSON 序列化
│ ├── JsonParser
│ ├── JsonReader
│ └── JsonWriter
├── Binary # 二进制序列化
├── Xml # XML 序列化
│ ├── XmlParser
│ └── XmlComposite
└── SpanSerializer # Span 零分配序列化
CsvFile / CsvDb<T> # CSV 读写
ExcelReader / ExcelWriter # Excel 读写
SpanReader / SpanWriter / SpanHelper # 缓冲区工具(NewLife.Buffers)
PooledByteBufferWriter # 池化缓冲写入器
SerialHelper # 序列化辅助
SafeInt64Converter / LocalTimeConverter # 类型转换器
```
### 2.5 配置系统(M5)
```
IConfigProvider (接口)
├── FileConfigProvider
│ ├── JsonConfigProvider (默认)
│ ├── XmlConfigProvider
│ └── IniConfigProvider
├── HttpConfigProvider # 远程配置(星尘)
├── ApolloConfigProvider # Apollo 配置中心
└── CompositeConfigProvider
Config<T> # 泛型配置基类(单例)
SysConfig # 系统配置(继承 Config<T>)
ConfigHelper # 配置辅助
CommandParser # 命令行解析
```
### 2.6 安全加密(M6)
```
SecurityHelper # RSA/AES/DES/MD5/SHA/CRC 统一方法集
RSAHelper # RSA 非对称加密
DSAHelper # DSA 数字签名
SM4 # 国密对称加密
RC4 # 流加密算法
Crc16 / Crc32 # CRC 循环冗余校验
Murmur128 # MurmurHash3 128 位哈希
IPasswordProvider # 密码哈希与验证接口
Rand # 安全随机数生成
PKCS7PaddingTransform # PKCS7 填充/去填充算法
Asn1 / Asn1Tags # ASN.1 数据格式编解码
```
### 2.7 应用框架(M7)
```
ObjectContainer # IoC/DI 容器(兼容 IServiceProvider)
Host # 后台服务托管(Windows 服务 + Linux Systemd)
IPlugin / PluginManager # 插件框架
Actor # Actor 并发模型
IMessageCodec / MessagePump # 协议编解码 / 消息帧泵(取代 IPipeline)
DeferredQueue # 延迟批处理队列
IMessage # 请求-响应消息接口
IEventBus / EventBus # 事件总线
EventHub<T> # 主题路由事件中心
```
### 2.8 缓存系统(M8)
```
ICache (接口)
├── MemoryCache # 内存缓存(含 MemoryQueue<T>)
└── Redis # ⚠️ 已提取到 NewLife.Redis
ICacheProvider # 缓存提供者
Cache / CacheLock # 缓存基类 / 分布式锁
IProducerConsumer<T> # 生产者消费者接口
QueueEventBus<T> # 消息队列事件总线
Pool<T> / ObjectPool<T> # 对象池(NewLife.Collections)
```
### 2.9 数据与算法(M9)
```
IModel # 模型数据接口(字符串键索引)
IExtend # 扩展数据接口(扩展属性字典)
IFilter / FilterContext # 数据过滤器(责任链)
IPacket (接口,零拷贝数据包;切片统一为引用计数共享)
├── ArrayPacket # byte[] 包装
└── OwnerPacket # 内存持有者包装(引用计数内核)
IPacketEncoder / DefaultPacketEncoder # 数据包编码器
Pipe / PipeReader / PipeWriter # 数据管道(字节流缓冲、水位背压、零拷贝窗口,全 TFM)
LimitedReader # 限长读取(帧体预算)
RingBuffer # 环形缓冲区(通用结构;协议组包已由数据管道 + 帧泵承担)
Snowflake # 雪花 ID(分布式唯一 ID)
GeoHash / GeoPoint # 经纬度哈希
DbTable / DbRow # 内存数据表
IInterpolation / ISampling / AlignModes # 采样插值框架抽象
AverageSampling # 降采样
LinearInterpolation # 线性插值
IData # 网络数据帧抽象
```
### 2.10 网络通信(M10)
```
NetServer # 网络服务器基类
├── TcpServer # TCP 服务器(unix:// 路径时走 Unix 域套接字)
└── UdpServer # UDP 服务器
NetClient # 统一 TCP/UDP/Unix 客户端
NetSession # 高级网络会话
IMessageCodec (协议编解码接口)
├── SrmpCodec # SRMP 标准消息(请求-响应配对)
├── LengthFieldCodec # 长度字段粘包拆包
├── SplitDataCodec # 分割字节粘包拆包
├── WebSocketCodec # WebSocket 编解码
└── CompressedCodec # 压缩装饰器(组合变换层)
MessagePump # 消息帧泵(管道上定界交付)
INetHandler (会话级数据处理器,旁路预处理)
IMatchQueue / DefaultMatchQueue # 消息匹配队列(请求响应配对)
HttpServer # 轻量级 HTTP 服务器
├── HttpRouter # 路由
├── StaticFilesHandler # 静态文件
├── ControllerHandler # MVC 控制器
└── CorsMiddleware 等 # 中间件
TinyHttpClient # 内网极简 HTTP 客户端(HTTP/1.1 基础子集,分块解码与 HttpSession 共用 ChunkedDecoder)
DnsHttpHandler # 自定义 DNS 解析处理器
HttpTraceHandler # APM 追踪处理器
WebSocket / WebSocketClient # WebSocket 支持(接收侧 RFC 6455 分片重组)
```
### 2.11 Web 工具(M11)
```
JwtBuilder # JWT 令牌生成/解码/验证
TokenProvider # 分布式数字签名令牌
WebClientX # 增强型 HTTP 下载(多线程断点续传)
PluginHelper # 插件加载与配置辅助
IObjectStorage (接口) # 对象存储抽象
└── EasyClient # 文件存储 HTTP 客户端(对接 EasyIO/OSS)
TokenHttpFilter # HTTP 令牌过滤器(自动注入与续期)
```
### 2.12 压缩归档(M12)
```
TarFile # Tar/Tar.Gz 归档操作
SevenZip # 7z 压缩解压(自动下载 7z.exe)
```
### 2.13 RPC 通信(M13)
```
ApiHttpClient # 多节点 HTTP API 客户端
ILoadBalancer # 负载均衡接口
├── FailoverLoadBalancer # 故障转移
├── WeightedRoundRobinLoadBalancer # 加权轮询
└── RaceLoadBalancer # 竞速模式
IServiceResolver # 服务发现与客户端实例管理
ApiHelper # API 调用辅助方法
```
## 3. 关键设计决策
| 决策 | 选择 | 理由 |
|------|------|------|
| 项目结构 | 单项目 + 目录分区 | 符合两层起步理念,减少维护成本 |
| 命名空间 | 每目录一个独立命名空间 | 清晰模块边界,便于按需引用 |
| 多目标框架 | net45~net10.0(11 个 TFM,含 3 个 -windows 变体) | 最大兼容性,Stub 目录填充缺失类型 |
| 目标框架精简 | 只保留在役版本 + net6 桥:net45/net461/net462/netstandard2.0/netstandard2.1/net6.0(-windows)/net8.0(-windows)/net10.0(-windows);删除 netcoreapp3.1、net5.0(-windows)、net7.0(-windows)、net9.0(-windows) | 已 EOL 的 TFM 每个约占 2.9 MB 资产;NuGet 会回退到最近的更低兼容资产,运行时不受影响,代价是条件编译造成的类型缺失(net7 回退 net6 丢 `DataMemberResolver`/`ServiceTypeResolver`,net5/3.1 回退 ns2.1 丢 `JsonConverter<,>`/`TypeConverter`);net6 仍有实际用户且回退到 ns2.1 损失最大,故保留一对作桥 |
| 移动端 TFM | 不增设 net10.0-android / net10.0-ios,移动端消费 net10.0 资产 | 基础库无平台专有 API;平台差异用运行时判断;避免 workload 成为全仓构建前置、包体膨胀与资产分叉;平台 TFM 只属于 App/UI 宿主或直接调用平台 API 的类库 |
| 移动端平台信息 | Android 用运行时反射 + `/proc`;iOS 用 `sysctl` + `os_proc_available_memory`;不新增移动 TFM | 避免 workload 绑定源码构建;电池/温度/CPU 占用/稳定设备标识由宿主 `IMachineInfo` 补充 |
| 移动端日志 | 宿主用 `Logger`/`ActionLog` + `TextFileLog` + `CompositeLog`;Core 不新增 `UseAndroid`/`UseiOS` | UI sink 绑定平台 UI;开箱即用需求走独立平台包,避免平台依赖进入主库 |
| 日志设计 | `ILog` 接口 + `XTrace` 静态门面 | 兼顾 DI 注入和静态便捷访问 |
| 缓存设计 | `ICache` 统一接口 | 内存/Redis/自定义实现可互换 |
| 序列化 | 自研高性能实现 | 避免依赖第三方库,控制性能 |
| 网络库 | 全异步 Socket | 单机实测 2266 万 tps |
| 数据包 | `IPacket` 零拷贝切片 | 网络层核心性能优化点 |
| 数据包所有权 | 引用计数共享切片(`Slice` 各自释放、引用归零归还;接收轮末按轮句柄 `RefCount` 裁决复用或换新) | 跨轮共享安全 + 零拷贝,消除借用视图悬垂与拷贝代偿 |
| 编解码 | `MessagePump` 帧泵 + 无状态 `IMessageCodec` 单栈(头部到齐即交付、大帧流式体) | 整删 `PacketCodec` 与 Handlers 处理器族;协议实例可跨连接共享,统一整帧与流式两态 |
| 生态兼容 | 旧版兼容壳按需保留:三参 `Slice` 保留 `[Obsolete]` 壳(二进制兼容面,语义已统一为引用计数共享);`Free`/`Rent`/`Return` 等壳删除 | 大版本破坏性变更下按下游迁移成本逐项取舍兼容面 |
| 协议契约扩展 | `IMessageCodec` 不新增成员、不改变继承关系 | 该接口是生态实现最多的契约,加成员或加继承会使全部外部实现者 `TypeLoadException`;能力差异经 `IMessageMatcher`(配对)、`IMessageCodecDecorator`(装饰器逐层解包)与明确的 `NotSupportedException` 表达 |
| 帧交付编排 | TCP 与 UDP 共享匹配语义(`IMatchQueue` + 共享 `ResponseMatcher`),交付编排各自实现,不抽统一调度器 | 两种传输形态的循环差异大,抽取会把消息泵循环与数据报循环硬编在一起,收益仅为代码组织 |
| 会话状态权威 | 六处状态收敛为「一个终态(`Disposed`)+ 一个存在性(`Sessions`)+ 若干派生量」,以文档 + XML 注释 + 契约用例固化,不合并结构 | `ISocketClient.Active` 为公开可写属性、`ISocketServer.Sessions` 形态被 `HttpServer` 与生态直接消费,收窄或合并会断旧二进制 |
| 会话类型模型 | `UdpSession` 不继承 `SessionBase`;`IStreamSession` 只建模管道,不含流式发送能力 | 基类接收环围绕独占 Socket 设计,UDP 为共享 Socket 按远端分片;给 `IStreamSession` 加发送成员会断实现者 |
| UDP 会话级拉取收口 | `UdpSession.Receive/ReceiveAsync` 不再直读共享 Socket,直接抛 `NotSupportedException` 并指引替代入口(`UdpServer` 拉取需 `AutoReceive=false`、`NetClient`、`Received` 事件);拉取统一归 `UdpServer`(`SessionBase`);会话级 `Timeout` 同步收口(不再写共享 Socket 的 `ReceiveTimeout`,仅为 `ITransport` 契约保留) | 服务器 Socket 为多会话共享:按会话过滤拉取会静默丢弃其他会话的数据报,且与服务器级拉取/接收环争抢同一 Socket;生态与仓储扫描无会话级拉取调用点。被否方案:委派 `Server.Receive()` 会把别人的数据报交给调用方;保留带过滤的拉取等于保留已知逻辑错误 |
| WebSocket 帧循环 | 服务端与客户端保持双帧循环,不合并 | 合并属组织性重构、无行为收益 |
| TcpSession 组织 | 按概念重分 partial 文件(生命周期 / 接收 / 发送 / 出站队列 / 消息泵 / 平台差异桥),发送编排收敛为 `SendUnderLock` 骨架,条件编译全部集中到 Platform 文件;**不抽独立协作类型** | 组织性重构的收益在可读性:同一概念一个文件、失败策略只写一处、主逻辑零 `#if`;抽独立类型(发送泵/泵宿主/传输桥各自成类)会引入跨对象生命周期与回调耦合,收益不抵风险(与「WebSocket 帧循环不合并」同一口径)。桥接层保持行为与分配契约不变(静态 lambda 传参,直发路径零闭包分配) |
| HTTP 派发 | 处理器契约异步(`Task ProcessRequestAsync`),会话级派发保持同步 | 会话级异步派发需一并解决响应保序、请求体跨轮所有权与低版本线程本地上下文传递 |
| 网络栈已知容忍项 | `Upgrade._Client` 不补释放、`SendAllAsync` 逐会话 `Task.Run`、`NetHelper.ParseEndPoint` 域名解析失败抛异常(坏端口等格式非法返回 null)、WebSocket 发送不分片(大帧整帧构建) | 均为权衡后有意保留的现状,理由见各类型 XML 注释 |
| TinyHttpClient 定位 | 只服务内网高吞吐的 HTTP/1.1 基础子集:http/https、KeepAlive、定长体与分块传输、整次请求超时、重定向;其余(1xx、非 chunked 传输编码、压缩、Cookie、认证、代理、连接池、RPC)一律显式抛异常,不静默降级 | 生态 60+ 仓库与 Core 生产代码均无调用,唯一使用者是自身测试;按通用客户端标准补协议覆盖只增复杂度。RPC 归 `ApiHttpClient`,通用 HTTP 归 `System.Net.Http.HttpClient`(全部 TFM 均可用);分块解码与 `HttpSession` 共用 `ChunkedDecoder` |
| IoC | `ObjectContainer` 自研 | 轻量级,兼容 `IServiceProvider` |
| 负载均衡 | 故障转移/加权轮询/竞速 | 覆盖不同场景需求 |
| Remoting 生态迁移 | 拆端口方案:SRMP 保留 `Port`,HTTP/WebSocket 独立 `HttpPort`(默认 `Port + 1`) | 对齐单一协议栈模型,各协议各走独立端口;来源:NewLife.Remoting ChangeLog(2026-10-05) |
| AOT 兼容 | 主链路以泛型/Type 入口保留注解 + 源生成器静态表承接;动态能力(插件/脚本/DLR/表达式编译)声明性排除 | 支撑 NativeAOT 原生发布(31 场景实测 + CI 防回归),边界见《AOT兼容性分析》 |
| 零调用公开面保留清单 | `MapPut`/`MapDelete`、`IHttpContext.WriteJson/WriteHtml/Redirect`、`NetHelper.GetDhcps/MyIPv6`、`NetUri.GetEndPoints`、`EventHub.EventBuses`、`NetServer.WriteError`、`FormFile.SaveToDirectory`、`DbTable.ToDataTable/LoadRows/SaveCsv/LoadCsv`、`PacketHelper.CopyPrefix`(测试支撑) | 2026-10 全生态(`C:\X` 50+ 仓库)核验零调用,但均属刻意公开的便捷/对称 API、虚方法契约或测试支撑;删除收益低而外部 NuGet 破坏面不可知,v12 保留并防重复报告 |
| 零仓库引用但生态在用成员 | `MapEmbedded`(Agent)、`WebSocketClient.SetRequestHeader`(AI/Remoting)、`NetHelper.GetMac/GetMacs/GetDns/GetGateways/GetMulticasts/GetRelativeEndPoint`、`ReceiveString`(NewLife.Net/Stardust/XCoder)、`IVectorStore`/`VectorRecord`(StarChat/NovaDb)、`DbTable.WriteData`(XCode/AntJob) | 库内文本扫描看不到生态调用;公开面"零引用"结论必须以 `C:\X` 全生态搜索为准,禁止仅凭库内扫描判死 |
| 零引用扫描误报类别 | P/Invoke 布局字段(`MEMORYSTATUSEX`、`MIB_TCPROW` 端口字节)、框架回调覆写(`LogEventListener` 等)、调试器反射契约(`Stub.ObjectIdForDebugger`)、多态与 TFM 变体(`OnParse`/`OnWrite`/`OnRead`/`RefreshWindows`) | 文本级扫描的固有误报:无静态引用但由布局/运行时/调试器/多态调用;这些成员保留,勿再按零引用清理 |
| 多语言 | 英文源文 + 内置译文表;默认跟随 `CurrentUICulture`,`Culture`/`LogCulture` 可强制;缺翻译回退英文 | 未接入组件行为不变;异常、日志与配置注释共用同一套文本 | 详见《多语言本地化》 |
## 4. 组件依赖关系
```
┌─────────────────┐
│ M1 基础扩展 │ ← 零依赖,被所有模块使用
└────────┬────────┘
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ M2 日志 │ │ M3 定时 │ │ M4 序列化│
└────┬─────┘ └──────────┘ └────┬─────┘
│ │
┌────┴─────┐ ┌──────┴──────┐
│ M5 配置 │ │ M6 安全加密 │
└────┬─────┘ └──────┬──────┘
│ │
┌────┴──────────────┐ │
│ M7 应用框架 │ │
└────┬──────────────┘ │
│ │
┌────┴──────────────┐ │
│ M8 缓存系统 │◄───────────┘
└────┬──────────────┘
│
┌────┴──────────────┐
│ M9 数据与算法 │
└────┬──────────────┘
│
┌────┼────────────────┐
▼ ▼ ▼
┌──────┐ ┌──────────┐ ┌──────────┐
│M10 │ │M11 Web │ │M13 RPC │
│网络 │ │工具 │ │通信 │
└──┬───┘ └──────────┘ └──────────┘
│
▼
┌──────────┐
│M12 压缩 │
│归档 │
└──────────┘
```
## 5. 编码约定
见项目根目录 `.editorconfig` 和 `global.json`。
| 约定 | 说明 |
|------|------|
| 类型名 | .NET 正式名:`String`/`Int32`/`Boolean`(非 `string`/`int`/`bool`) |
| Nullable | 全局启用 `<Nullable>enable</Nullable>` |
| 语言版本 | `<LangVersion>latest</LangVersion>`(C# 14) |
| 文档注释 | XML 注释所有 public/protected 成员,`<summary>` 同行闭合 |
| 签名 | 强命名(`newlife.snk`) |
## 6. 安全切片收口记录(令牌与 WebSocket)
> 2026-10 安全角度切片扫描(令牌体系 + WebSocket)的收口:准入线内问题已修复并清理(原 FIX-130~FIX-132);本节记录**已核查、按准入线不处理/不上报**的事项与干净结论,扫描该切片前先读本节,避免重复报告。
| 事项 | 位置 | 处置与理由 |
|------|------|-----------|
| WebSocket 实现整体(握手/掩码/帧边界/分片/控制帧/UTF-8) | `Http\WebSocket.cs`、`Net\WebSocketClient.cs`、`Messaging\WebSocketCodec.cs` 等 | **干净结论(2026-10)**:逐行核查未发现准入线内问题——双端掩码强制(方向反转即 1002)、帧长度与分片 16MB 上限(超限 1009)、控制帧 FIN/≤125 字节、关闭码白名单与 UTF-8 截断保护、文本消息严格 UTF-8 校验(非法 1007)均已按 RFC 6455 落实 |
| 掩码键使用非加密随机(`Random.Shared.NextBytes`) | `Messaging\WebSocketCodec.cs` | 不修。违反 RFC 6455 §5.3「strong entropy」的规范事实成立(`Security\Rand.cs` 已用 `RandomNumberGenerator`,一行可对齐),但客户端为本方可信代码、掩码不承担保密职责,构造不出有实质后果的触发路径 |
| `TokenProvider` 默认密钥 DSA-1024 | `Security\DSAHelper.cs` | 不修。算法强度已弃用,但无现实可执行攻击路径;更换默认属破坏性变更,留待大版本评估 |
| `RSAHelper` 静态共享 `HashAlgorithm` 并发非线程安全 | `Security\RSAHelper.cs` | 不修(理论竞态)。并发下或致验签偶发失败(可用性问题),无「误判为通过」路径;改实例化会动公开面与性能,暂缓 |
| `JwtBuilder` 对 `exp` 缺失/异常值按无过期放行(`Year > 2000` 判定) | `Web\JwtBuilder.cs` | 不修(可选加固)。本库 `Encode` 恒写 `exp`;第三方签发不写 `exp` 属边界场景,如需可加「必须带 exp」开关,待真实需求 |
| `TokenHttpFilter` 密码 OAEP 加密、Action 匹配、401/403 清缓存、并发获取去重 | `Http\TokenHttpFilter.cs` | 按设计,未见绕过面(2026-10 扫描结论) |
## 7. 收口记录(跨 TFM 兼容切片)
> 2026-10 跨 TFM 二进制兼容门禁(Microsoft Package Validation,`Tools/Scripts/check-api-compat.ps1`)专项的收口:本节记录**已决策保留抑制/不修/临时豁免**的事项与理由。维护 `NewLife.Core\CompatibilitySuppressions.xml` 或扫描兼容面前先读本节,避免重复报告与误删条目。
| 事项 | 位置 | 处置与理由 |
|------|------|-----------|
| `DynamicDependencyAttribute.set_AssemblyName` 垫片与 net6.0 BCL 成员差 | `NewLife.Core\Stub\CodeAnalysisAttributes.cs`、`CompatibilitySuppressions.xml`(CP0002,netstandard2.1→net6.0) | **抑制恢复(2026-10-19)**:目标框架精简后资产边界变为 netstandard2.1→net6.0,跨资产对比仍会命中该成员差(门禁实测);原 `DynamicallyAccessedMemberTypes.Interfaces` 字段差已不再出现,无需保留。差异本身属 BCL 版本漂移:垫片按完整特性定义,net6.0 BCL 上该属性只读;特性成员缺失仅影响元数据反射,无运行时故障 |
| `TimeProvider.set_System`(垫片可写注入钩子 vs net8+ BCL 只读属性) | `NewLife.Core\Common\TimeProvider.cs`、`CompatibilitySuppressions.xml`(CP0002,net6.0→net8.0) | **抑制恢复(2026-10-19)**:net6.0 垫片仍产出,跨资产对比(net6.0→net8.0)仍会命中该成员差(门禁实测),此前"精简后不再对比"的判断不成立。公开面差异仍在:垫片带 setter 供低版本注入自定义时间;net8+ BCL 为只读。已知边界:net45~net6 编译的消费者在现代宿主调用 setter 会 `MissingMethodException`(setter 仅垫片存在),接受并记录 |
| `PooledByteBufferWriter.WriteToStreamAsync` 低 TFM 返回类型 Task→ValueTask 对基线包的 4 条 CP0002 | `NewLife.Core\Buffers\PooledByteBufferWriter.cs`、`CompatibilitySuppressions.xml`(`IsBaselineSuppression`×4) | **临时抑制(v12 有意破坏性变更)**:低 TFM 统一为 ValueTask,修复 ns2.0 编译库在现代宿主调用的 `MissingMethodException`(探针实证)。**已闭环(2026-10-17)**:`12.0.2026.1017-beta0404` 发布后 4 条抑制失配,已删除并复跑门禁 EXIT=0;本条保留为决策记录 |
| `IBinary.ReadBytes(Span<Byte>)` 全 TFM 暴露对基线包的 4 条 CP0006 | `NewLife.Core\Serialization\Binary\IBinary.cs`、`CompatibilitySuppressions.xml`(`IsBaselineSuppression`×4) | **临时抑制(v12 有意破坏性变更)**:接口成员由 ns2.1+ 独占放宽为全 TFM 暴露(System.Memory 已为低 TFM 提供 Span),消除接口实现者跨资产类型加载风险。实施前已扫描 `C:\X` 全生态与本仓:IBinary 仅本仓 `Binary` 一个实现者,无外部实现者。**已闭环(2026-10-17)**:`12.0.2026.1017-beta0404` 发布后 4 条抑制失配,已删除并复跑门禁 EXIT=0;本条保留为决策记录 |
> 使用要点:`CompatibilitySuppressions.xml` 中带 `<IsBaselineSuppression>true</IsBaselineSuppression>` 的条目只匹配"基线包 vs 当前包同 TFM"诊断(Left/Right 相同);跨 TFM 条目无该元素(Left/Right 为不同 TFM 资产)。删除抑制条目后必须运行 `Tools/Scripts/check-api-compat.ps1` 确认 EXIT=0——门禁同时检查"不必要的抑制",条目失配同样报错。
>
> **过渡期例外(2026-10-18)**:目标框架精简后首次发布前,基线包仍含 netcoreapp3.1/net5.0/net7.0/net9.0 资产,门禁会把这些基线与精简后的资产配对,报出一批跨 TFM 差异(BCL 版本漂移与 EOL 回退损失)。这是**一次性过渡噪声**,基线切换到精简后的包后自动消失;本机 `Tools/Scripts/check-api-compat.ps1` 在该窗口内退出码非 0 属预期,不必新增抑制(新增反而会在下一版被判"不必要")。**已结束(2026-10-19)**:基线 `12.0.2026.1018-beta1517` 已使用精简后的资产集合,门禁 EXIT=0,后续不再按过渡期噪声处理。
## 8. 收口记录(覆盖率盲区)
> 2026-10 行级覆盖率专项(一次性采样,报告口径见会话 `.tmp` 产物)的收口:本节记录**已决策不补测/不处理**的盲区与理由;做覆盖率分析或补测规划前先读本节,避免重复清点。凡已登记 IMP/FIX 工单的缺口不在此列。
| 事项 | 位置 | 处置与理由 |
|------|------|-----------|
| 旧 XML 配置 `XmlConfig<TConfig>`(152 行 0%) | `NewLife.Core\Xml\XmlConfig.cs` | 维持不测。`[Obsolete]` 旧版实现,替代品为 Json/Ini 等 provider;为废弃代码补测无收益 |
| `OrcasNamer`(108 行 0%,全仓无引用) | `NewLife.Core\Reflection\OrcasNamer.cs` | 不删除、不补测:公开类型,外部消费者不可知,删除属破坏性变更,待大版本评估(与"零调用公开面保留清单"同口径) |
| 旧 Json 栈(`Json.cs`/`JsonComposite`/`JsonArray`/`JsonDictionary`/`JsonGeneral` ≈199 行 0%) | `NewLife.Core\Serialization\Json\` | 暂停处置:新栈为 `JsonParser/Writer/Reader + JsonHelper`;旧栈废弃策略(标 `[Obsolete]` 或删除)待大版本决策,暂不补测 |
| 平台专属分支(`MachineInfo.Linux/Container/MacOS`、`Windows\ConsoleHelper` 等) | 同名文件 | 环境性盲区:本机 Windows 采样执行不到 Linux/macOS 分支;CI 的 linux/osx 矩阵已实际执行对应代码,本地覆盖率数字不代表未验证 |
| `ApolloConfigProvider.GetAll` 异常仅 Debug 记录 | `Configuration\ApolloConfigProvider.cs` | 不修:`LoadAll` 已按失败返回 false 并在 `GetAll` 外层告警,逐层重复告警收益低 |
| `GetLinksInDirectory` 对重叠通配模式返回重复链接(如 `*.gz;*.tar.gz`) | `Web\WebClientX.cs` | 不修:同一文件被两个模式各命中一次,对"按版本取最新"无实质影响;去重属调用方职责 |
| `HttpConfigProvider.GetAll` 对 null 载荷返回 null(`LoadAll` 视为失败) | `Configuration\HttpConfigProvider.cs` | 维持:与"无配置空字典"区分是合理语义(null=服务端异常/无响应),失败可感知语义已由 FIX-144 补齐 |
| 失败态单次索引器访问触发两次 `EnsureLoad`(索引器与 `Find` 各一次) | `Configuration\IConfigProvider.cs` | 不修(微优化):仅故障期间网络尝试翻倍;与 FIX-145"失败即下次重试"(已实现)配套,后续如需要可加最小重试间隔统一治理 |
|