Services 服务体系
7. Services 服务体系
位置:Source/Services
服务层负责“能力”,不直接关心 UI 细节。
| 服务项目 | 功能 |
|---|---|
H.Services.AppPath | 应用路径,如程序目录、配置目录、数据目录。 |
H.Services.Common | 公共服务接口,如数据库连接、主题加载、启动页、引导等。 |
H.Services.Identity | 用户、角色、权限、登录、注册。 |
H.Services.Logger | 日志服务接口和日志命令。 |
H.Services.Mail | 邮件发送。 |
H.Services.Message | 消息、对话框、通知、Snack。 |
H.Services.Operation | 操作日志。 |
H.Services.Project | 项目文件、新建、打开、保存。 |
H.Services.Revertible | 撤销、重做。 |
H.Services.Serializable | JSON、XML、克隆、Web 序列化。 |
H.Services.Setting | 设置项、设置页面、配置存取。 |
典型思路:
- 服务接口放在
Services。 - UI 展示放在
Modules或Presenters。 - 应用在
ConfigureServices中注册具体实现。 - 运行时通过
Ioc.GetService<T>()获取。
Services 服务体系详解
一、服务层概述
服务层是 WPF-Control 框架的能力中心,负责封装各种业务功能和基础设施能力。
核心原则:服务负责能力,不直接关心 UI 细节。
二、服务体系架构
2.1 服务分类
┌─────────────────────────────────────────────────────────────┐ │ Services │ ├─────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ AppPath │ │ Identity │ │ Logger │ │ │ │ 应用路径 │ │ 用户权限 │ │ 日志服务 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Mail │ │ Message │ │ Operation │ │ │ │ 邮件发送 │ │ 消息通知 │ │ 操作日志 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Project │ │ Revertible │ │ Serialize │ │ │ │ 项目管理 │ │ 撤销重做 │ │ 序列化 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Setting │ │ Common │ │ │ │ 设置管理 │ │ 公共服务 │ │ │ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘2.2 服务职责表
| 服务项目 | 核心功能 | 关键接口 |
|---|---|---|
| H.Services.AppPath | 应用路径管理 | IAppPathServce |
| H.Services.Common | 公共服务接口 | ISplashScreenViewPresenter,IThemeViewPresenter |
| H.Services.Identity | 用户认证授权 | ILoginService,IAuthority,IUser |
| H.Services.Logger | 日志记录 | ILogService,LogCommand |
| H.Services.Mail | 邮件发送 | IMailService |
| H.Services.Message | 消息通知 | IMessageService,ISnackMessageService |
| H.Services.Operation | 操作日志 | IOperationLogService |
| H.Services.Project | 项目管理 | IProjectService |
| H.Services.Revertible | 撤销重做 | IRevertibleService |
| H.Services.Serializable | 序列化 | ISerializeService |
| H.Services.Setting | 设置管理 | ISettingService,ISettingViewPresenter |
三、核心服务详解
3.1 AppPath - 应用路径服务
功能介绍
IAppPathServce提供应用运行时所需的各种路径:
| 属性 | 说明 | 示例路径 |
|---|---|---|
AppPath | 程序安装目录 | C:\Program Files\MyApp |
AppName | 应用名称 | MyApp |
Version | 应用版本 | 1.0.0.0 |
Config | 配置目录 | C:\ProgramData\MyApp\Config |
Data | 数据目录 | C:\ProgramData\MyApp\Data |
Log | 日志目录 | C:\ProgramData\MyApp\Log |
Setting | 设置目录 | C:\ProgramData\MyApp\Setting |
UserPath | 用户目录 | C:\Users\Admin\AppData\Roaming\MyApp |
UserData | 用户数据目录 | C:\Users\Admin\AppData\Roaming\MyApp\Data |
UserSetting | 用户设置目录 | C:\Users\Admin\AppData\Roaming\MyApp\Setting |
使用示例
// 获取路径服务IAppPathServcepathService=Ioc.GetService<IAppPathServce>();// 获取各种路径stringlogPath=pathService.Log;// 日志目录stringdataPath=pathService.Data;// 数据目录stringsettingPath=pathService.Setting;// 设置目录// 静态方式访问(推荐)stringuserData=AppPaths.Instance.UserData;3.2 Logger - 日志服务
接口定义
publicinterfaceILogService{voidInfo(stringmessage);voidError(stringmessage);voidError(Exceptionex);voidWarn(stringmessage);voidDebug(stringmessage);voidTrace(stringmessage);}使用示例
// 方式一:通过 IOC 获取ILogServicelogger=Ioc.GetService<ILogService>();logger.Info("应用启动");logger.Error("发生错误",ex);// 方式二:使用静态类(推荐)IocLog.Instance.Info("用户登录成功");IocLog.Instance.Error(ex);3.3 Message - 消息服务
消息类型
| 类型 | 用途 | 示例 |
|---|---|---|
| Dialog | 模态对话框 | 确认删除、提示信息 |
| Snack | 底部通知条 | 操作成功提示 |
| Notice | 通知消息 | 系统通知 |
使用示例
// 显示对话框awaitIoc.GetService<IMessageService>().ShowMessageAsync("操作成功","提示");// 显示确认对话框boolresult=awaitIoc.GetService<IMessageService>().ShowConfirmAsync("确定要删除吗?","确认删除");// 显示 Snack 消息Ioc.GetService<ISnackMessageService>().Show("保存成功");3.4 Identity - 身份认证服务
核心接口
// 用户接口publicinterfaceIUser{stringId{get;}stringName{get;}stringAccount{get;}}// 登录服务publicinterfaceILoginService{Task<bool>Login(stringaccount,stringpassword);voidLogout();boolIsLogined{get;}IUserCurrentUser{get;}}// 权限服务publicinterfaceIAuthority{boolHasPermission(stringpermission);boolHasRole(stringrole);}使用示例
// 登录ILoginServiceloginService=Ioc.GetService<ILoginService>();boolsuccess=awaitloginService.Login("admin","password");if(success){IocLog.Instance.Info($"用户{loginService.CurrentUser.Name}登录成功");}// 权限检查IAuthorityauthority=Ioc.GetService<IAuthority>();if(authority.HasPermission("Delete")){// 执行删除操作}3.5 Setting - 设置服务
功能介绍
设置服务负责管理应用的配置项:
publicinterfaceISettingService{TGetSetting<T>(stringkey);voidSetSetting<T>(stringkey,Tvalue);voidSave();voidLoad();}使用示例
ISettingServicesettingService=Ioc.GetService<ISettingService>();// 读取设置stringtheme=settingService.GetSetting<string>("Theme");intfontSize=settingService.GetSetting<int>("FontSize");// 保存设置settingService.SetSetting("Theme","Dark");settingService.SetSetting("FontSize",14);settingService.Save();3.6 Serializable - 序列化服务
功能介绍
提供多种序列化方式:
| 方法 | 说明 |
|---|---|
ToJson() | 对象转 JSON |
FromJson() | JSON 转对象 |
ToXml() | 对象转 XML |
FromXml() | XML 转对象 |
Clone() | 对象深拷贝 |
使用示例
ISerializeServiceserializeService=Ioc.GetService<ISerializeService>();// 对象转 JSONMyDatadata=newMyData{Name="Test",Value=100};stringjson=serializeService.ToJson(data);// JSON 转对象MyDatarestored=serializeService.FromJson<MyData>(json);// 对象克隆MyDatacloned=serializeService.Clone(data);四、服务使用流程
4.1 服务注册
在ConfigureServices中注册服务:
publicpartialclassApp:ApplicationBase{protectedoverridevoidConfigureServices(IServiceCollectionservices){// 注册路径服务services.AddAppPath();// 注册日志服务(使用 log4net)services.AddLog4net();// 注册消息服务services.AddAdornerDialogMessage();services.AddSnackMessage();// 注册身份认证服务services.AddIdentity();// 注册设置服务services.AddSetting();// 注册序列化服务services.AddSerialize();}}4.2 服务获取
运行时通过 IOC 容器获取服务:
// 方式一:直接获取(常用)varlogger=Ioc.GetService<ILogService>();// 方式二:安全获取(不抛异常)varoptionalService=Ioc.GetService<IMyOptionalService>(throwIfNone:false);if(optionalService!=null){optionalService.DoSomething();}// 方式三:静态类访问(推荐用于常用服务)IocLog.Instance.Info("日志消息");4.3 服务注入
在构造函数中注入服务:
publicclassMyPresenter{privatereadonlyILogService_logService;privatereadonlyIMessageService_messageService;// 通过构造函数注入publicMyPresenter(ILogServicelogService,IMessageServicemessageService){_logService=logService;_messageService=messageService;}publicvoidDoSomething(){_logService.Info("执行操作");_messageService.ShowMessage("操作完成");}}五、服务设计原则
5.1 接口优先
// ✅ 推荐:依赖接口publicclassMyService:IMyService{}// ❌ 不推荐:直接依赖具体类publicclassMyService{}5.2 单一职责
// ✅ 推荐:一个服务只做一件事publicinterfaceILogService{}// 日志服务publicinterfaceIMessageService{}// 消息服务// ❌ 不推荐:胖接口publicinterfaceIAllInOneService{voidLog();voidSendMessage();voidSaveSetting();}5.3 无状态设计
// ✅ 推荐:无状态服务publicclassLogService:ILogService{publicvoidInfo(stringmessage){// 直接写入日志,不保存状态File.AppendAllText("log.txt",message);}}六、服务扩展模式
6.1 创建自定义服务
步骤1:定义接口
publicinterfaceIMyService{voidDoWork(stringparam);Task<string>GetDataAsync();}步骤2:实现服务
publicclassMyService:IMyService{publicvoidDoWork(stringparam){// 实现逻辑}publicasyncTask<string>GetDataAsync(){// 异步操作returnawaitTask.FromResult("data");}}步骤3:创建扩展方法
publicstaticclassMyServiceExtension{publicstaticIServiceCollectionAddMyService(thisIServiceCollectionservices){services.TryAddSingleton<IMyService,MyService>();returnservices;}}步骤4:注册服务
protectedoverridevoidConfigureServices(IServiceCollectionservices){services.AddMyService();}6.2 服务配置选项
// 定义配置类publicclassMyServiceOptions{publicstringApiUrl{get;set;}="http://localhost:5000";publicintTimeout{get;set;}=30;}// 扩展方法publicstaticIServiceCollectionAddMyService(thisIServiceCollectionservices,Action<MyServiceOptions>setupAction=null){services.AddOptions();if(setupAction!=null)services.Configure(setupAction);services.TryAddSingleton<IMyService,MyService>();returnservices;}// 使用services.AddMyService(options=>{options.ApiUrl="http://api.example.com";options.Timeout=60;});七、服务层与其他层的关系
┌─────────────────────────────────────────────────────────────┐ │ UI Layer │ │ Controls / Presenters / Views │ ├─────────────────────────────────────────────────────────────┤ │ Modules │ │ 功能模块组合 │ ├─────────────────────────────────────────────────────────────┤ │ Services │ │ 能力提供层 │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Logger │ │ Message │ │ Setting │ │ AppPath │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ ├─────────────────────────────────────────────────────────────┤ │ IOC │ │ 服务连接与管理 │ └─────────────────────────────────────────────────────────────┘调用关系
View/Presenter │ ├─→ Ioc.GetService<IMessageService>() │ │ │ ▼ │ MessageService.Show() │ ├─→ Ioc.GetService<ILogService>() │ │ │ ▼ │ LogService.Info() │ └─→ Ioc.GetService<ISettingService>() │ ▼ SettingService.GetSetting()八、总结
服务层是 WPF-Control 框架的能力核心,具有以下特点:
- 职责清晰:每个服务只负责一类能力
- 松耦合:通过接口定义,便于替换实现
- 可测试:依赖注入使单元测试更简单
- 可扩展:通过扩展方法轻松添加新服务
掌握服务体系的使用,是开发高质量 WPF 应用的关键。
