StdUnit.Tags
2.0.0-alpha
dotnet add package StdUnit.Tags --version 2.0.0-alpha
NuGet\Install-Package StdUnit.Tags -Version 2.0.0-alpha
<PackageReference Include="StdUnit.Tags" Version="2.0.0-alpha" />
<PackageVersion Include="StdUnit.Tags" Version="2.0.0-alpha" />
<PackageReference Include="StdUnit.Tags" />
paket add StdUnit.Tags --version 2.0.0-alpha
#r "nuget: StdUnit.Tags, 2.0.0-alpha"
#:package StdUnit.Tags@2.0.0-alpha
#addin nuget:?package=StdUnit.Tags&version=2.0.0-alpha&prerelease
#tool nuget:?package=StdUnit.Tags&version=2.0.0-alpha&prerelease
这是一个面向串行轮询读写场景的 .NET 类库家族:把一组只能周期性读写的资源表达成一棵测点树,再为其提供一套严格串行的交互机制。
目前的主打用例都是工业现场通信——我们内置了S7/OpcUa/ModbusTcp 等驱动。但有意思的是,这里的抽象本身,其实与硬件无关。它面向的是没有事件 API、只能粗暴轮询的场景。例如,需要周期性监控服务器的资源消耗情况(Linux 甚至为此提供了 procfs/sysfs)、或者想要周期性监控某些网站上公开信息的变化。对于这些需求,我们只要为它们单独定制一套驱动,就可以共享同一套抽象机制。
这既不是一个开箱即用的产品,也不是一个framework,而是一个library家族。它的核心是一组统一的、可扩展的通信抽象,以及在此基础之上提供的开箱即用的交互方式。目前,我们只提供一种交互方式:严格的串行轮询(有意地模仿了 PLC 的扫描机制)。
- 执行外部意图
- 读入数据
- 处理逻辑
- 刷写底层
我们把它定位成library的一个初衷是,希望它能被灵活地组合到各种场景中,而不是仅仅被当做一个项目模板
拷来拷去。1.0.0 及以后的相关包都已经发布到 nuget.org。主要变化参见 CHANGELOG.md。
当然,如果你需要自动创建模板,我们也提供了StdUnit.Tags.Templates,参见下面的 Quick Start。
Quick Start
你可以仅使用这个类库中的通信功能;不过我们更推荐你采用它默认的交互方式,你只管提供描述(xml),我们负责让它跑起来。
我们提供了模板来快速创建脚手架
dotnet new install StdUnit.Tags.Templates
然后即可以创建相关模板项目:
dotnet new tags.wpf -n your-project.name # 这会创建一个 WPF 模板项目
dotnet new tags.web -n your-project.name # 这会创建一个 ASP.NET Core 项目
想要创建你新的硬件驱动库?
dotnet new tags.driver -n your-project.name -D YourDriver
备注:这里-D是给你的驱动起的名字
优势:
- 硬件无关抽象:理论上,你可以在家里用S7模拟器编写自动化测试,验证你的逻辑,最后到现场前再切换到
OpcUa设备上(或者反过来)。或者你不想用任何模拟器的话,可以直接使用“测点即文件”的功能,用文件系统来测试你的S7、OpcUa逻辑。 - “测点即文件”: 添加
StdUnit.Tags.SimpleFiles支持,可以把测点树映射为文件树,让你轻松读写和变更配置。配合R1W+IsScanned,可以尽可能减少文件系统的访问次数。 - 业务逻辑插件化:
netcore上支持逻辑组件插件(dll),各插件的依赖相互隔离、支持卸载和热更(netfx上降级支持,见“netfx 的插件化限制”)。 - 支持通过MCP方式暴露给AI:把测点项目描述作为上下文,让AI可以轻松操作你的设备
文档
- 我为本类库编写了教程,部署在tags.doc。
- 仓库内
docs/放框架性内容:核心模型、外部意图与死锁、扩展点、错误处理、设计决策与边界(范围与运行期契约、CI 取舍、兼容与命名、打包与发布);详细使用说明见上一点。 - 本仓库自带的Samples: 主要用于开发验证+喂狗。(其中
samples/WpfDemo是 WPF 示例,只期望 Windows SDK,因此不在解决方案内;需要时在本机用dotnet build samples/WpfDemo/WpfDemo.csproj单独构建。) - 供新手熟悉功能WPFDemo: 按分支演示功能。
文件夹结构与驱动支持
.configdotnet-tools.json: 本项目用到的 dotnet tools 配置
global.json: 本项目SDK配置,目前锁定版本8.0.102src/: 项目代码及测试StdUnit.Tags.Core: 核心抽象;其Schemas/目录持有项目描述 XML 的 XSD(tagsproject.xsd)StdUnit.Tags.SchemaGenerator: 源生成器,把各项目的 XSD 编译为 DLL 内常量(AOT/trim 友好)StdUnit.Tags: 基本功能,但和具体的硬件设备无关,只依赖于StdUnit.Tags.Core。StdUnit.Tags.RxExtensions:dotnet/reactive扩展,只依赖于StdUnit.Tags.CoreStdUnit.Tags.R3Extensions:Cysharp/R3扩展,只依赖于StdUnit.Tags.CoreStdUnit.Tags.S7: 西门子S7协议扩展,只依赖于StdUnit.Tags+ Sharp7StdUnit.Tags.OpcUaClient: OpcUa客户端扩展,依赖于StdUnit.Tags+ OpcUaStdUnit.Tags.ModbusTcp: ModbusTcp扩展,依赖于StdUnit.Tags+ NModbusStdUnit.Tags.Hjzk: Hjzk IO盒子扩展,依赖于StdUnit.Tags.ModbusTcp- ... 其它硬件扩展
StdUnit.Tags.BlazorLib.Core: Blazor 类库,包含核心功能抽象,以及一个极简的监控页面。StdUnit.Tags.BlazorLib: 包含一些常用硬件设备的实现。StdUnit.Tags.McpServer: 这是一个把StdUnit.Tags暴露成 Model Context Protocol Server 的类库。StdUnit.Tags.Tests: 上述子项目的测试(多目标net8.0+net472)StdUnit.Tags.Tests.NetCoreOnly: 仅net8.0的测试项目,专门存放无法面向 net472 的测试(Blazor / ASP.NET Core 等)。目前为空项,占位预留。
samples/: 示例代码paket.dependencies: 用paket管理的依赖声明paket.lock: 依赖锁定文件
其中一些驱动和扩展包的支持程度如下:
| 驱动及扩展 | 包名 | 状态 |
|---|---|---|
| 简单文件 | StdUnit.Tags.SimpleFiles |
✅ 支持 |
| 西门子S7 | StdUnit.Tags.S7 |
✅ 支持 |
| OpcUA | StdUnit.Tags.OpcUaClient |
✅ 支持 |
| 华杰智控IO盒子 | StdUnit.Tags.Hjzk |
✅ 支持 |
| ModbusTcp | StdUnit.Tags.ModbusTcp |
🧪 实验 |
| 串口 | StdUnit.Tags.ComScanner |
🧪 实验 |
| 卓兰IO盒子 | StdUnit.Tags.ZLan |
🧪 实验 |
| Rx扩展 | StdUnit.Tags.RxExtensions |
✅ 支持 |
| R3扩展 | StdUnit.Tags.R3Extensions |
✅ 支持 |
| McpServer扩展 | StdUnit.Tags.McpServer |
✅ 支持 |
| BlazorLibCore扩展 | StdUnit.Tags.BlazorLib.Core |
✅ 支持 |
上表列出的包中,标记为“实验”的,<Major>.<Minor>.<Patch> 里的 <Minor> 跳变可能包含破坏性更新;标记为“支持”的,只有 <Major> 跳变才可能包含破坏性更新。核心包(StdUnit.Tags、StdUnit.Tags.Core)不属于驱动/扩展、因此不在此表内,按语义化版本处理——同样只有 <Major> 跳变才可能包含破坏性更新。
警告:有一些未在本仓库中列出的驱动及扩展,却由我发布到公开的
nuget.org上以及私有的测试源上(比如StdUnit.Tags.LinuxFs.ProcInfo、StdUnit.Tags.WinUsbKeyboardCodeScanners),只供内部使用——那部分包不对外提供任何质量保证,请谨慎使用。
目标框架
本项目家族同时支持 net8.0 与 net472(.NET Framework 4.7.2),以便逐步迁移中的旧系统也能用上同一套抽象:
| 子项目 | 目标框架 |
|---|---|
StdUnit.Tags.Core / StdUnit.Tags |
net8.0 + net472 |
StdUnit.Tags.RxExtensions / StdUnit.Tags.R3Extensions |
net8.0 + net472 |
StdUnit.Tags.S7 / ModbusTcp / Hjzk / ZLan / OpcUaClient / ComScanner / SimpleFiles |
net8.0 + net472 |
StdUnit.Tags.McpServer |
net8.0 + net472(经 ModelContextProtocol 核心包的 netstandard2.0 资产) |
StdUnit.Tags.BlazorLib / BlazorLib.Core |
仅 net8.0 |
StdUnit.Tags.SchemaGenerator |
netstandard2.0(源生成器) |
两个框架的能力差异(目前只有一处,即插件化的隔离与卸载):见 netfx 的插件化限制。
LICENSING
本仓库由许多子项目构成,根据上游依赖的不同,我们为每个子项目采用不同的授权协议。基本原则是在尊重上游依赖包授权的前提下,选择最友好的开源授权协议 (几乎都是 MIT,详见各仓库下的 LICENSE)。
- 我们自己编写的核心类库部分和部分硬件实现包,由于不涉及官方类库之外的第三方依赖,一律采用MIT协议。
- 除了OPC UA之外,所有涉及第三方依赖的实现包,其上游依赖都是MIT授权,所以这里我们也放心采用MIT协议。
- 目前唯一比较特殊的是OPC UA,我记得早期OPC基金会的仓库下基本都是GPL授权,不过最近我发现它们官方已经改成了OPC Foundation MIT License 1.00,所以我们也遵循这个开源协议——OPC Foundation MIT License 1.00
开发计划
开发计划与待办事项见 backlog.md。
netfx 的插件化限制
net472 没有 AssemblyLoadContext,无法做到「按目录隔离 + 可卸载」的插件加载,
因此 <Logicet> 插件在该框架下退化为 Assembly.LoadFrom:
- 仍然可用:插件可以独立编译、单独发布,再挂载到宿主——「宿主开发与插件开发分离」的能力保留;
- 无依赖隔离:插件依赖与宿主同名程序集冲突时以先加载者为准,不会为插件目录单独建立加载上下文;
- 无法卸载:
project停止不会释放插件程序集,插件dll在宿主进程退出前一直被锁定; 同一路径的插件重新编译后,若不重启宿主,可能仍运行旧代码。
加载时会输出 WARNING 日志提示上述限制。若需要完整能力(隔离 + 卸载 + 热更新),请使用 net8.0。
上述限制不影响在宿主内注册逻辑组件(
TryAddLogicet<TLogicet>),该方式在两个框架下都可用。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 Framework | net472 is compatible. net48 was computed. net481 was computed. |
-
.NETFramework 4.7.2
- FSharp.Core (>= 8.0.100)
- IsExternalInit (>= 1.0.3)
- Microsoft.Extensions.DependencyInjection (>= 8.0.1)
- Microsoft.Extensions.Logging (>= 8.0.0)
- StdUnit.Tags.Core (>= 2.0.0-alpha)
- System.Threading.Channels (>= 10.0.5)
-
net8.0
- FSharp.Core (>= 8.0.100)
- McMaster.NETCore.Plugins (>= 2.0.0)
- Microsoft.Extensions.DependencyInjection (>= 8.0.1)
- Microsoft.Extensions.Logging (>= 8.0.0)
- StdUnit.Tags.Core (>= 2.0.0-alpha)
NuGet packages (8)
Showing the top 5 NuGet packages that depend on StdUnit.Tags:
| Package | Downloads |
|---|---|
|
StdUnit.Tags.ModbusTcp
ModbusTcp 通信支持 |
|
|
StdUnit.Tags.BlazorLib.Core
Blazor 组件库(核心):测点树与通道的查看、编辑组件 |
|
|
StdUnit.Tags.SimpleFiles
简单文件支持,把测点树映射为文件树 |
|
|
StdUnit.Tags.OpcUaClient
OPC UA 通信支持 |
|
|
StdUnit.Tags.S7
西门子 S7 通信支持 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0-alpha | 40 | 10/10/2026 |
| 1.1.0 | 86 | 10/8/2026 |
| 1.0.0 | 108 | 10/7/2026 |