🧬 CoreUnify 基类
命名空间: Snet.Core | 类: CoreUnify<O, D> | 泛型参数: O(操作类型),D(数据/基础配置类型)
CoreUnify<O, D> 是所有 Snet 操作组件(协议驱动和中间件)的基础基类。它提供单例生命周期管理、统一的事件系统、计时仪表、日志记录、多语言支持等功能。
类型参数
| 参数 | 描述 | 示例 |
|---|---|---|
O |
具体的操作类型(自引用) | ModbusOperate |
D |
数据/基础配置类型 | ModbusData.Basics |
单例管理
每个 CoreUnify 子类被注册为单例,最多支持 255 个实例:
// 创建实例 -- 按类型进行单例管理
var op = await ModbusOperate.InstanceAsync(new ModbusData.Basics
{
IpAddress = "192.168.1.100",
Port = 502,
Station = 1
});
// 每种唯一的操作类型最多可以有 255 个实例
// 实例 ID 自动分配(1-255)
事件系统
CoreUnify 通过 IEvent 提供 3 对事件(共 6 个事件):
| 同步 | 异步 | 描述 |
|---|---|---|
OnDataEvent |
OnDataEventAsync |
当接收到数据时触发 |
OnInfoEvent |
OnInfoEventAsync |
当状态、信息和诊断消息时触发 |
OnLanguageEvent |
OnLanguageEventAsync |
当语言/区域设置变更时触发 |
// 注册处理器
op.OnDataEventAsync += async (sender, e) =>
{
Console.WriteLine($"数据: {e.Message}");
};
op.OnInfoEventAsync += async (sender, e) =>
{
Console.WriteLine($"信息: {e.Message}");
};
op.OnLanguageEventAsync += async (sender, e) =>
{
Console.WriteLine($"语言已更改: {e.Message}");
};
计时仪表
CoreUnify 通过 BegOperate 和 EndOperate 提供内置的操作计时:
// 计时是自动的 -- 每个操作都跟踪执行时间
var address = new Address(new AddressDetails("点", "40001", DataType.Int16));
var result = await op.ReadAsync(address);
Console.WriteLine($"操作耗时 {result.RunTime} ms");
// RunTime 由 BegOperate/EndOperate 计时机制自动填充
日志记录
CoreUnify 使用 Serilog 进行日志记录,日志级别由 Serilog.Events.LogEventLevel 枚举定义。标准 Serilog 级别包括:Verbose、Debug、Information、Warning、Error 和 Fatal。
多语言支持
// 设置语言为中文
await op.SetLanguageAsync(LanguageType.zh);
// 设置语言为英文
await op.SetLanguageAsync(LanguageType.en);
IInstance
在单例池中创建新实例。创建的实例会存储到单例匹配列表中——参数一致时返回历史对象。如需克隆(不注册单例),请使用 CloneThisAsync()(见下文)。
| 方法 | 签名 | 描述 |
|---|---|---|
CreateInstance<T> |
OperateResult CreateInstance<T>(T param) |
从类型化参数创建实例 |
CreateInstanceAsync<T> |
Task<OperateResult> CreateInstanceAsync<T>(T param, CancellationToken token = default) |
异步变体 |
CreateInstance |
OperateResult CreateInstance(string json) |
从 JSON 字符串创建实例 |
CreateInstanceAsync |
Task<OperateResult> CreateInstanceAsync(string json, CancellationToken token = default) |
异步 JSON 变体 |
// 使用新设置创建实例
var newOp = await op.CreateInstanceAsync(new ModbusData.Basics
{
IpAddress = "192.168.1.101",
Port = 502,
Station = 2
});
// result.ResultData 持有新的单例实例
// JSON 形式
var jsonResult = await op.CreateInstanceAsync(basicsJson);
GetArgs
获取当前的参数/配置:
// 获取当前的基础配置
var result = await op.GetArgsAsync(true);
if (result.Status)
{
// 基础数据对象在 result.ResultData 中
Console.WriteLine($"GetArgs 成功: {result.Message}");
}
UpdateArgs
更新实例创建后的基础配置:
// 使用类型化基础配置对象更新
var result = op.UpdateArgs(new ModbusData.Basics
{
IpAddress = "192.168.1.102",
Port = 502,
Station = 3
});
if (result.Status)
{
Console.WriteLine($"UpdateArgs succeeded: {result.Message}");
}
// 使用 JSON 字符串更新
var json = "{\"IpAddress\":\"192.168.1.103\",\"Port\":502,\"Station\":4}";
var result2 = op.UpdateArgs(json);
GetBasicsArgs
获取原始的基础数据对象(传入 InstanceAsync 的原始配置):
var result = op.GetBasicsArgs();
if (result.Status)
{
var basics = result.ResultData as ModbusData.Basics;
Console.WriteLine($"IP: {basics.IpAddress}, Port: {basics.Port}");
}
GetAutoAllocatingArgs
获取标记了 [AutoAllocatingTag] 特性的参数,用于自动配置:
// 仅获取自动分配的参数(配置的子集)
var result = await op.GetAutoAllocatingArgsAsync();
if (result.Status)
{
Console.WriteLine($"自动分配的参数: {result.ResultData}");
}
ExistsAutoAllocatingArgs
检查当前基础数据是否包含 [AutoAllocatingTag] 特性:
var result = op.ExistsAutoAllocatingArgs();
if (result.Status)
{
Console.WriteLine("此驱动支持自动分配参数");
}
CloneThis (IClone)
深度克隆当前操作实例,克隆对象不会注册到单例容器中:
// Clone 会创建一个完全独立的副本
var cloneResult = op.CloneThis();
if (cloneResult.Status)
{
// 克隆对象不在单例字典中
var clonedOp = cloneResult.ResultData as ModbusOperate;
// 独立使用 clonedOp — 它有自己的生命周期
}
继承链
CoreUnify<O, D> -- 单例、事件、计时、日志、语言
└── DaqAbstract<O, D> -- 读/写/订阅(用于协议驱动)
└── MqAbstract<O, D> -- 发布/消费(用于中间件)
└── ModbusOperate -- 具体协议实现
└── SiemensOperate -- 具体协议实现
└── MqttClientOperate -- 具体中间件实现
└── KafkaOperate -- 具体中间件实现
└── ... -- 等等
关键设计要点
- 单例模式 确保每个配置在 255 个实例限制内只有一个逻辑实例
- 所有方法都是异步的 -- 始终使用
await进行操作调用 - 事件同时使用同步和异步委托 -- 异步处理器顺序执行,同步处理器并行执行
- 计时是自动的 -- 每个操作结果都包含由
BegOperate/EndOperate测量的RunTime
