A:调整整体README

This commit is contained in:
jimmy committed 2025-12-11 16:53:33 +08:00
1 parent 26a2661625
commit 433e206d45
5 files changed
+166 -265

No files matched your search

+59 -265
View File
@@ -1,287 +1,81 @@
# sharp-basic
# Sharp Basic
C# 公共基础核心(模块化、多项目可复用)
一个基于 .NET 8 的现代化工业自动化与企业级应用开发套件,采用模块化架构设计,提供了从底层通信、基础设施到上层 UI 的完整解决方案。
sharp-basic 旨在将常用基础能力拆分为可独立复用的模块(库项目),帮助业务项目即取即用,减少样板代码与重复实现。
## 🏗️ 架构概览
当前仓库采用多项目结构,包含 Common、Config 等核心模块,以及 Logging、EventBus、NetClient/NetServer 等待实现或扩展的模块,同时提供 WPF/Client 示例项目便于演示与调试。
本项目包含以下核心模块,旨在实现高内聚、低耦合的开发体验:
## 功能概览
### 🔌 核心基础设施
- **[Sharp.Common](Common/README.md)**: 基础工具库。提供轻量级 DI 容器 (`Global`)、函数式结果模式 (`Result<T>`)、以及丰富的扩展方法(String, DateTime, Encryption, Reflection)。
- **[Sharp.Config](Config/README.md)**: 强大的配置管理。支持 JSON/XML/INI/TOML 多源聚合、强类型绑定和数据注解验证。
- **[Sharp.Log](Log/README.md)**: 统一日志门面。基于 Serilog 封装,支持一行代码接入,提供结构化日志和文件滚动策略。
- **[Sharp.EventBus](EventBus/README.md)**: (开发中) 轻量级事件总线。
- 通用工具(Sharp.Common)
- 结果类型 Result/Result<T>:统一成功/失败表达、错误码/异常、Map/Bind/LINQ 风格链式操作、同步/异步 Try 包装
- 轻量服务容器 Global:线程安全注册与获取(Singleton/Transient)、实例变更通知(订阅发布)、批量管理
- 实用工具与扩展:JSON 序列化选项与 IPAddress 转换、端口探测、管理员权限检测、字符串解析等
- 配置中心(Sharp.Config)
- 统一构建器:支持 Json/Ini/Xml/Toml 多源叠加、可选/必选、基路径/文件提供器、环境变量、热重载
- 强类型绑定与验证:DataAnnotations 递归验证、TryGet/异常详情、对象保存与读取(多格式序列化)
- 扩展钩子:自定义 IConfigurationBuilder 管道(ConfigureBuilderHook)
- 日志(Sharp.Log)【规划中】
- 基于 Microsoft.Extensions.Logging 的统一抽象,适配 Console/File/Serilog/NLog,结构化日志与上下文
- 事件总线(Sharp.EventBus)【规划中】
- 进程内发布订阅、异步/顺序/粘性事件,支持 WPF 弱订阅;外部 Broker(Redis/RabbitMQ/Kafka)适配扩展
- 网络(Sharp.NetClient / Sharp.NetServer)【规划中】
- HttpClientFactory 封装、重试熔断超时、请求签名、统一 Result<T> 返回;最小 API Host 与中间件
- 桌面工具(Sharp.Wpf / Sharp.Client)
- WPF 示例/样板,用于演示配置热更、事件订阅、日志等集成的参考
### 💾 数据与存储
- **[Sharp.Data](Data/README.md)**: 极简数据访问层。基于 EF Core,提供开箱即用的仓储模式、自动审计(创建人/时间)、软删除和分页支持。
- **[Sharp.Repository](Repository/README.md)**: 数据库集成模块。通过配置切换 SQL Server/MySQL/PostgreSQL/Sqlite,支持自动迁移。
## 目录结构
### 🌐 网络与通信
- **[Sharp.NetServer](NetServer/README.md)**: 轻量级 Web 框架。基于 `HttpListener`,提供类似 ASP.NET Core 的 Controller/Route/Middleware 开发体验,适合嵌入式或桌面应用内嵌 Web 服务。
- **[Sharp.NetClient](NetClient/README.md)**: 强类型 HTTP 客户端。集成 Polly 重试策略、Bearer Token 认证和 multipart 上传。
- **[Sharp.Ports](Ports/README.md)**: 串口通信库。提供串口发现、连接管理、数据监听和诊断工具。
```
src/Sharp/
Common/ # 通用能力(Result、Global、Utils、扩展)
Config/ # 配置集中管理与序列化
Log/ # 日志抽象(规划中)
EventBus/ # 事件总线(规划中)
NetClient/ # 客户端网络(规划中)
NetServer/ # 服务端网络(规划中)
Wpf/ # WPF 示例
Client/ # WPF 示例(另一个样板)
test/
Common.Test/ # Common 核心用例(MSTest)
### 🏭 工业互联 (IIoT)
- **[Sharp.Plc](Plc/README.md)**: PLC 通信抽象层。定义了统一的读写、订阅接口。
- **[Sharp.Plc.Siemens](Plc.Siemens/README.md)**: 西门子驱动实现。支持 S7-200/300/400/1200/1500,内置智能批量读取优化算法(自动合并相邻地址请求)。
### 🖥️ 桌面应用 UI
- **[Sharp.Wpf](Wpf/README.md)**: WPF 基础库。提供 MVVM 基类、全局异常捕获、常用转换器、对话框服务和行为扩展。
- **[Sharp.Client](Client/README.md)**: 综合客户端示例。集成 PLC 监控、串口调试和用户登录功能的工业控制台应用。
- **[Sharp.Server](Server/README.md)**: 服务器控制台示例。展示了如何在一个 WPF 应用中托管 NetServer Web 服务,并提供可视化管理界面。
## 🚀 快速开始
### 环境要求
- .NET 8.0 SDK
- Visual Studio 2022 或 VS Code
### 构建项目
```bash
# 还原依赖
dotnet restore
# 编译解决方案
dotnet build Sharp.sln -c Debug
```
目标框架:.NET 8(net8.0 / net8.0-windows)。
### 运行示例
## 快速开始
> 当前未发布 NuGet 包,可在解决方案内直接引用相关项目,或将模块作为子模块引入你的解决方案。
### 使用 Result 统一返回
```csharp
using Common.Results;
Result<int> r1 = Result.Success(123);
Result r2 = Result.Failure("something wrong");
// Try 模式(同步/异步)
var r3 = Result.Try(() => int.Parse("456"));
var r4 = await Result.TryAsync(async () => { await Task.Delay(10); return 789; });
// Map/Bind 链式管道
var r5 = r3.Map(x => x * 2).Where(v => v > 500, "too small");
// 提取值(或异常)
int value = r5.GetOrDefault(0); // 成功取值,否则默认
int must = r5.GetOrThrow(); // 失败抛出异常
**1. 运行 WPF 客户端:**
```bash
dotnet run --project Client/Client.csproj
```
### 使用 Global 注册与订阅
```csharp
using Common;
// 注册单例(实例/工厂),与瞬态
Global.RegisterSingleton(new AppConfig { AppName = "MyApp", Version = "1.0" });
Global.RegisterSingleton(() => new CacheService());
Global.RegisterTransient(() => new RequestContext());
// 订阅服务变更
Global.Subscribe<AppConfig>(e =>
{
Console.WriteLine($"Config changed: {e.OldValue?.Version} -> {e.NewValue.Version}");
});
// 更新将触发订阅回调
Global.Update(new AppConfig { AppName = "MyApp", Version = "1.1" });
// 获取
var config = Global.Get<AppConfig>();
**2. 运行嵌入式 Web 服务器:**
```bash
dotnet run --project Server/Server.csproj
```
示例类型(自定义)
```csharp
public sealed class AppConfig { public string AppName { get; set; } = ""; public string Version { get; set; } = ""; }
public sealed class CacheService { }
public sealed class RequestContext { public string RequestId { get; set; } = Guid.NewGuid().ToString(); }
**3. 运行 NetServer 纯控制台示例:**
```bash
dotnet run --project NetServer/Examples
```
### 配置管理(多源叠加/强类型/验证/保存)
## 🧪 测试
```csharp
using Sharp.Config;
// 1) 从多个文件构建(支持 Json/Ini/Xml/Toml),并启用环境变量与热重载
var cfg = ConfigBuilder.Build(opt =>
{
opt.BasePath = AppContext.BaseDirectory;
opt.ReloadOnChange = true;
opt.IncludeEnvironmentVariables = true;
opt.EnvironmentPrefix = "MYAPP_"; // 可选
opt.Sources.Add(new ConfigSource { Path = "appsettings.json", Format = ConfigFormat.Json, Optional = false });
opt.Sources.Add(new ConfigSource { Path = "appsettings.Development.json", Format = ConfigFormat.Json, Optional = true });
});
// 2) 强类型绑定 + 验证(DataAnnotations)
var options = cfg.Get<MyOptions>(validate: true);
// 3) 热重载回调
using var _ = cfg.OnReload(() => Console.WriteLine("Configuration reloaded"));
// 4) 保存/读取对象(跨格式序列化)
cfg.Save(options, path: "out/appsettings.toml", format: ConfigFormat.Toml);
var reloaded = cfg.LoadFromFile<MyOptions>("out/appsettings.toml", ConfigFormat.Toml);
public sealed class MyOptions
{
[System.ComponentModel.DataAnnotations.Required]
public string Name { get; set; } = string.Empty;
public int Port { get; set; } = 8080;
}
```
示例 appsettings.json
```json
{
"name": "demo",
"port": 5000
}
```
## 测试
- 测试框架:MSTest(并行执行)。
- 运行:
项目包含完整的单元测试,位于解决方案同级的 `test` 目录中。
```bash
dotnet test
# 运行所有测试
dotnet test Sharp.sln
```
核心用例位于 `test/Common.Test`,覆盖 Result 与 Global 的主要功能与边界场景。
## 🤝 贡献指南
欢迎提交 Pull Request 或 Issue。请确保:
1. 代码风格符合 .NET 规范。
2. 新增功能包含对应的单元测试。
3. 提交信息简洁明了。
## WPF 工具包(Sharp.Wpf)
提供即插即用的 WPF 常用基础能力:
- 全局异常处理:统一捕获 UI/后台/未观察任务异常,支持弹窗与自定义日志
- MVVM 基础:`ViewModelBase`(INPC/IsBusy)、`RelayCommand`、`AsyncCommand`
- Dispatcher 封装:`IDispatcher`/`DispatcherService`,提供 UI 线程调用统一入口
- 对话与文件对话:`IDialogService`、`IFileDialogService`
- 常用转换器:Bool/NullOrEmpty 可见性、布尔取反、枚举描述
- 附加行为:EventToCommand(事件转 ICommand)
- 窗口工具:`WindowPlacement` 窗口位置/大小/状态持久化
### 引用
在你的 WPF 项目中添加项目引用:
```xml
<!-- Client/Client.csproj -->
<ItemGroup>
<ProjectReference Include="..\Wpf\Wpf.csproj" />
<!-- 或通过 NuGet: <PackageReference Include="Sharp.Wpf" Version="x.y.z" /> -->
</ItemGroup>
```
### 全局异常处理(App 启动)
```csharp
// App.Startup.cs
using System.Windows;
using Sharp.Wpf.Exceptions;
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
new UiExceptionHandler().Register(new ExceptionHandlingOptions
{
ShowDialog = true,
DialogTitle = "应用程序错误"
});
}
}
```
### XAML 集成(窗口位置、行为、转换器)
```xml
<Window x:Class="Client.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:b="clr-namespace:Sharp.Wpf.Behaviors;assembly=Sharp.Wpf"
xmlns:w="clr-namespace:Sharp.Wpf.Windowing;assembly=Sharp.Wpf"
xmlns:conv="clr-namespace:Sharp.Wpf.Converters;assembly=Sharp.Wpf"
Title="MainWindow"
w:WindowPlacement.RememberPlacement="True"
w:WindowPlacement.PlacementId="MainWindow">
<Window.Resources>
<conv:BoolToVisibilityConverter x:Key="Bool2Vis" />
</Window.Resources>
<StackPanel Margin="16">
<Button Content="点击弹窗"
b:EventToCommand.EventName="Click"
b:EventToCommand.Command="{Binding ShowDialogCommand}" />
<Button Content="触发异常"
b:EventToCommand.EventName="Click"
b:EventToCommand.Command="{Binding ThrowCommand}" />
<TextBlock Text="正在处理..."
Visibility="{Binding IsBusy, Converter={StaticResource Bool2Vis}}"/>
</StackPanel>
</Window>
```
### ViewModel 与命令
```csharp
using System;
using System.Threading.Tasks;
using Sharp.Wpf.Commands;
using Sharp.Wpf.Mvvm;
using Sharp.Wpf.Services;
public sealed class MainViewModel : ViewModelBase
{
private readonly IDialogService _dialog = new DialogService();
public string Greeting { get; set; } = "欢迎使用 Sharp.Wpf";
public IAsyncCommand ShowDialogCommand { get; }
public RelayCommand ThrowCommand { get; }
public MainViewModel()
{
ShowDialogCommand = new AsyncCommand(async () =>
{
try { IsBusy = true; await Task.Delay(300); await _dialog.ShowInfoAsync("Hello!"); }
finally { IsBusy = false; }
});
ThrowCommand = new RelayCommand(() => throw new InvalidOperationException("演示未处理异常"));
}
}
```
### 文件对话
```csharp
var files = await new FileDialogService().OpenFilesAsync("Images|*.png;*.jpg");
var folder = await new FileDialogService().SelectFolderAsync();
```
## 路线图(Roadmap)
- P0(最优先)
- Logging 抽象与 Serilog 适配;EventBus 进程内 Typed 事件;Config 对接 IOptions 与变更广播
- P1
- Net.Client:HttpClientFactory 封装 + Result<T> 模式;WPF Toolkit:MVVM/事件聚合/通知与主题
- P2
- 可靠性(Polly)、OpenTelemetry、外部 Broker 适配(Redis/RabbitMQ/Kafka)、敏感字段加密
- P3
- 文档/示例完善、CI/CD(自动打包发布)、更多单测与性能基准
## 贡献与规范
- 欢迎通过 Issue/PR 参与贡献。
- 代码风格:.NET 8、可空启用、简化 `using`,命名空间建议统一为 `Sharp.*`(Common 模块后续将统一为 `Sharp.Common`)。
- 变更需保持向后兼容(次版本),破坏式变更请在主版本发布并注明迁移指南。
## 许可
本项目采用 GNU AGPLv3 许可证,详见根目录 `LICENSE`。
如需在私有环境或商业场景中使用且不希望开源网络服务端改动代码,请联系作者洽谈其他授权方式。
## 📄 许可证
MIT License
+44
View File
@@ -0,0 +1,44 @@
# Sharp.Client
基于 WPF 的工业客户端应用程序示例,展示了如何集成套件中的各个模块(PLC、串口、配置、日志、MVVM)。
## 功能概览
- **用户登录**:基于 `Sharp.Data` 的用户验证。
- **PLC 监控**:展示 `Plc.Siemens` 模块的使用,实时读取/写入 PLC 数据。
- **串口调试**:集成 `Ports` 模块,提供串口发现、连接与数据收发界面。
- **MVVM 架构**:使用 `Sharp.Wpf` 提供的 ViewModelBase、Command 和 DialogService。
## 关键集成点
### 1. 启动初始化 (App.xaml.cs)
展示了如何按顺序初始化基础设施:
- 加载配置 (`Sharp.Config`)
- 初始化日志 (`Sharp.Log`)
- 配置数据库 (`Sharp.Data`)
- 注册服务到 DI 容器 (`Sharp.Common.Global`)
### 2. PLC 交互 (PlcWindow)
- 演示了 `IPlcService` 的使用。
- 订阅模式(Subscribe) vs 即时读取(ReadAsync)。
- UI 绑定与数据转换。
### 3. 串口通信 (SerialPortWindow)
- 串口列表刷新与选择。
- 16进制与 ASCII 模式切换。
- 数据收发日志。
## 开发指南
1. 确保已安装 .NET 8 SDK。
2. 运行项目:
```bash
dotnet run --project Client.csproj
```
3. 默认登录账号(如使用示例数据库):`admin` / `123456`(需自行在初始化时播种)。
## 目录结构
- `Hardware/`: 硬件抽象层(如扫码枪、打印机接口)。
- `Services/`: 客户端特定服务(如 `LoginService`)。
- `ViewModels/`: MVVM 视图模型。
- `Views/`: XAML 窗口与控件。
+12
View File
@@ -0,0 +1,12 @@
# Sharp.EventBus
> **🚧 开发中 / Under Construction**
这是一个预留的事件总线模块,计划用于实现进程内(In-Process)或分布式(Distributed)的消息发布/订阅模式。
## 计划功能
- 定义统一的 `IEventBus` 接口。
- 提供基于内存(Channel/MemoryCache)的默认实现。
- 提供集成 RabbitMQ / Redis 的扩展实现。
目前该目录仅包含占位符。
+46
View File
@@ -0,0 +1,46 @@
# Sharp.Server
基于 WPF 的服务器控制台/仪表盘应用,集成了 `Sharp.NetServer` 作为内置 HTTP 服务端,演示了“桌面应用 + Web 服务”的混合架构。
## 功能特性
- **可视化控制**:通过 WPF 界面启动/停止 HTTP 服务。
- **实时日志**:在界面上显示服务器运行日志(集成 `Sharp.Log`)。
- **数据管理**:内置 SQLite 数据库管理界面(集成 `Sharp.Data`)。
- **混合架构**:
- 前台:WPF UI 用于运维和监控。
- 后台:`NetServer` 提供 REST API 供局域网设备/客户端调用。
## 架构说明
### 核心组件
- **ServerService**: 封装 `HttpServer` 的生命周期管理(启动、停止、重启)。
- **AppConfig**: 使用 `Sharp.Config` 映射的强类型配置。
- **Controllers**: API 控制器,处理来自网络的 HTTP 请求。
### 启动流程 (App.xaml.cs)
1. **配置**:加载 `appsettings.json`。
2. **日志**:初始化 Serilog 并绑定到 UI 输出。
3. **数据库**:初始化 EF Core Context。
4. **Web服务**:实例化 `ServerService` 但不立即启动(由用户点击按钮触发,或配置为自动启动)。
## 配置 (appsettings.json)
```json
{
"Server": {
"Host": "0.0.0.0",
"Port": 5000,
"UseAuth": true
},
"Database": { ... }
}
```
## 使用说明
1. 启动应用。
2. 点击“启动服务”按钮。
3. 状态栏显示“运行中”,并显示监听地址(如 `http://localhost:5000`)。
4. 使用浏览器或 Postman 访问 API(如 `/api/health`)。
5. 点击“数据管理”可查看存储在本地 SQLite 中的数据。
+5
View File
@@ -0,0 +1,5 @@
# Sharp.Infrastructure
基础设施层项目,通常用于存放解决方案级别的横切关注点或胶水代码,目前包含部分遗留配置或共享类型。
> **注意**:随着模块化重构的进行,本项目的许多职责已迁移至 `Common`、`Config` 等专门模块。当前主要作为兼容性保留或特定业务的基础设施依赖。