本文说明项目的主要运行面、模块职责和边界关系,而不逐项枚举所有源码文件。
DataAcquisition 的主产品是 Edge Agent。
其他模块均应围绕该采集链路理解其职责边界。
位置:
src/DataAcquisition.Domain
职责:
- 定义配置模型
- 定义采集消息
- 定义受控值类型和归一化规则
- 定义不会依赖具体库的基础模型
这里不应该知道 Hsl、InfluxDB、SQLite 或 ASP.NET。
位置:
src/DataAcquisition.Application
职责:
- 定义运行时抽象
- 定义 PLC 驱动接口
- 定义存储接口
- 定义配置、队列、采集相关契约
这一层回答的是:
- 上层需要什么能力
- 而不是这些能力如何实现
位置:
src/DataAcquisition.Infrastructure
职责:
- 提供默认实现
- 封装 Hsl 驱动
- 封装 InfluxDB
- 封装 SQLite 日志和状态存储
- 实现配置热更新、指标和诊断
这是项目里最大的实现层,但不应该反向定义上层抽象。
位置:
src/DataAcquisition.Edge.Agent
职责:
- 作为采集宿主进程启动整个系统
- 注册默认实现
- 运行后台 Worker
- 暴露本地健康、指标、日志和诊断接口
如果你只关心“项目真正做什么”,先看这一层。
位置:
src/DataAcquisition.Central.Apisrc/DataAcquisition.Central.Web
职责:
- 提供中心化状态查看
- 展示心跳、指标和诊断代理
它们是控制面,不是采集主链路。
位置:
tests/DataAcquisition.Core.Tests
职责:
- 验证驱动配置契约
- 验证队列批次行为
- 验证条件采集状态恢复逻辑
- 验证配置校验
DataAcquisition 的核心链路很固定:
Edge Agent启动- 加载设备配置
- 为每个设备创建 PLC 驱动
- 启动心跳与采集任务
- 生成
DataMessage - 进入
QueueService - 聚合成批次
- 直接写
InfluxDB - 写入失败时记录日志和指标,当前批次被丢弃
这条链路是判断模块边界是否合理的基准。
关键文件:
src/DataAcquisition.Application/Abstractions/IPlcDriverProvider.cssrc/DataAcquisition.Application/Abstractions/IPlcClientService.cssrc/DataAcquisition.Infrastructure/Clients/PlcClientFactory.cssrc/DataAcquisition.Infrastructure/Clients/HslStandardPlcDriverProvider.cssrc/DataAcquisition.Infrastructure/Clients/HslPlcClientService.cs
职责:
- 用稳定的
Driver名称选择具体 PLC 实现 - 屏蔽上层对 Hsl 的直接依赖
- 解析并应用驱动相关配置
这个设计的重点是:
- 核心框架不绑死在具体 PLC 类型枚举上
- Hsl 是默认实现,不是架构前提
关键文件:
src/DataAcquisition.Infrastructure/DataAcquisitions/DataAcquisitionService.cssrc/DataAcquisition.Infrastructure/DataAcquisitions/HeartbeatMonitor.cssrc/DataAcquisition.Infrastructure/DataAcquisitions/ChannelCollector.cssrc/DataAcquisition.Infrastructure/DataAcquisitions/ChannelMetricReader.cssrc/DataAcquisition.Infrastructure/DataAcquisitions/MetricExpressionEvaluator.cssrc/DataAcquisition.Infrastructure/DataAcquisitions/AcquisitionStateManager.cs
职责:
- 启动和管理采集任务
- 判断设备是否可采
- 执行 Always / Conditional 采集
- 读取字段、计算表达式、生成事件
- 恢复条件采集 active cycle 状态
关键文件:
src/DataAcquisition.Infrastructure/Queues/QueueService.cssrc/DataAcquisition.Infrastructure/DataStorages/InfluxDbDataStorageService.cs
职责:
- 批量聚合消息
- 直接写存储
- 通过日志和指标暴露写入失败
- 保持当前运行时的简单失败语义
这里是数据进入存储前最关键的一层。
关键文件:
src/DataAcquisition.Infrastructure/DeviceConfigs/DeviceConfigService.cssrc/DataAcquisition.Infrastructure/DeviceConfigs/DeviceConfigValidator.cssrc/DataAcquisition.Infrastructure/DeviceConfigs/DeviceConfigFileLoader.cssrc/DataAcquisition.Infrastructure/Logs/*src/DataAcquisition.Infrastructure/Metrics/*
职责:
- 读取和验证 JSON 配置
- 监控配置目录并热更新
- 提供 Prometheus 指标
- 提供本地日志查询
如果把这个项目做成长期维护的开源项目,我会坚持这些边界:
Domain不依赖基础设施库Application只定义契约Infrastructure只实现,不定义上层业务规则Edge Agent是主产品,不把中心服务当主链路- 文档只承诺真实支持的能力
做法:
- 实现新的
IPlcDriverProvider - 如有需要,提供新的
IPlcClientService - 在宿主层注册
- 提供完整
Driver名称和示例配置
做法:
- 实现
IDataStorageService - 替换宿主层默认注册
- 明确文档化你的成功/失败语义
做法:
- 修改
QueueService - 保持批量写入边界清晰
- 同步更新测试和文档中的失败语义
如果你想快速理解代码,推荐这个顺序:
README.mddocs/design.mdsrc/DataAcquisition.Edge.Agent/Program.cssrc/DataAcquisition.Infrastructure/DataAcquisitions/DataAcquisitionService.cssrc/DataAcquisition.Infrastructure/Queues/QueueService.cssrc/DataAcquisition.Infrastructure/Clients/HslStandardPlcDriverProvider.cs