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.SerializableJSON、XML、克隆、Web 序列化。H.Services.Setting设置项、设置页面、配置存取。典型思路服务接口放在Services。UI 展示放在Modules或Presenters。应用在ConfigureServices中注册具体实现。运行时通过Ioc.GetServiceT()获取。Services 服务体系详解一、服务层概述服务层是 WPF-Control 框架的能力中心负责封装各种业务功能和基础设施能力。核心原则服务负责能力不直接关心 UI 细节。二、服务体系架构2.1 服务分类┌─────────────────────────────────────────────────────────────┐ │ Services │ ├─────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ AppPath │ │ Identity │ │ Logger │ │ │ │ 应用路径 │ │ 用户权限 │ │ 日志服务 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Mail │ │ Message │ │ Operation │ │ │ │ 邮件发送 │ │ 消息通知 │ │ 操作日志 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Project │ │ Revertible │ │ Serialize │ │ │ │ 项目管理 │ │ 撤销重做 │ │ 序列化 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Setting │ │ Common │ │ │ │ 设置管理 │ │ 公共服务 │ │ │ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘2.2 服务职责表服务项目核心功能关键接口H.Services.AppPath应用路径管理IAppPathServceH.Services.Common公共服务接口ISplashScreenViewPresenter,IThemeViewPresenterH.Services.Identity用户认证授权ILoginService,IAuthority,IUserH.Services.Logger日志记录ILogService,LogCommandH.Services.Mail邮件发送IMailServiceH.Services.Message消息通知IMessageService,ISnackMessageServiceH.Services.Operation操作日志IOperationLogServiceH.Services.Project项目管理IProjectServiceH.Services.Revertible撤销重做IRevertibleServiceH.Services.Serializable序列化ISerializeServiceH.Services.Setting设置管理ISettingService,ISettingViewPresenter三、核心服务详解3.1 AppPath - 应用路径服务功能介绍IAppPathServce提供应用运行时所需的各种路径属性说明示例路径AppPath程序安装目录C:\Program Files\MyAppAppName应用名称MyAppVersion应用版本1.0.0.0Config配置目录C:\ProgramData\MyApp\ConfigData数据目录C:\ProgramData\MyApp\DataLog日志目录C:\ProgramData\MyApp\LogSetting设置目录C:\ProgramData\MyApp\SettingUserPath用户目录C:\Users\Admin\AppData\Roaming\MyAppUserData用户数据目录C:\Users\Admin\AppData\Roaming\MyApp\DataUserSetting用户设置目录C:\Users\Admin\AppData\Roaming\MyApp\Setting使用示例// 获取路径服务IAppPathServcepathServiceIoc.GetServiceIAppPathServce();// 获取各种路径stringlogPathpathService.Log;// 日志目录stringdataPathpathService.Data;// 数据目录stringsettingPathpathService.Setting;// 设置目录// 静态方式访问推荐stringuserDataAppPaths.Instance.UserData;3.2 Logger - 日志服务接口定义publicinterfaceILogService{voidInfo(stringmessage);voidError(stringmessage);voidError(Exceptionex);voidWarn(stringmessage);voidDebug(stringmessage);voidTrace(stringmessage);}使用示例// 方式一通过 IOC 获取ILogServiceloggerIoc.GetServiceILogService();logger.Info(应用启动);logger.Error(发生错误,ex);// 方式二使用静态类推荐IocLog.Instance.Info(用户登录成功);IocLog.Instance.Error(ex);3.3 Message - 消息服务消息类型类型用途示例Dialog模态对话框确认删除、提示信息Snack底部通知条操作成功提示Notice通知消息系统通知使用示例// 显示对话框awaitIoc.GetServiceIMessageService().ShowMessageAsync(操作成功,提示);// 显示确认对话框boolresultawaitIoc.GetServiceIMessageService().ShowConfirmAsync(确定要删除吗,确认删除);// 显示 Snack 消息Ioc.GetServiceISnackMessageService().Show(保存成功);3.4 Identity - 身份认证服务核心接口// 用户接口publicinterfaceIUser{stringId{get;}stringName{get;}stringAccount{get;}}// 登录服务publicinterfaceILoginService{TaskboolLogin(stringaccount,stringpassword);voidLogout();boolIsLogined{get;}IUserCurrentUser{get;}}// 权限服务publicinterfaceIAuthority{boolHasPermission(stringpermission);boolHasRole(stringrole);}使用示例// 登录ILoginServiceloginServiceIoc.GetServiceILoginService();boolsuccessawaitloginService.Login(admin,password);if(success){IocLog.Instance.Info($用户{loginService.CurrentUser.Name}登录成功);}// 权限检查IAuthorityauthorityIoc.GetServiceIAuthority();if(authority.HasPermission(Delete)){// 执行删除操作}3.5 Setting - 设置服务功能介绍设置服务负责管理应用的配置项publicinterfaceISettingService{TGetSettingT(stringkey);voidSetSettingT(stringkey,Tvalue);voidSave();voidLoad();}使用示例ISettingServicesettingServiceIoc.GetServiceISettingService();// 读取设置stringthemesettingService.GetSettingstring(Theme);intfontSizesettingService.GetSettingint(FontSize);// 保存设置settingService.SetSetting(Theme,Dark);settingService.SetSetting(FontSize,14);settingService.Save();3.6 Serializable - 序列化服务功能介绍提供多种序列化方式方法说明ToJson()对象转 JSONFromJson()JSON 转对象ToXml()对象转 XMLFromXml()XML 转对象Clone()对象深拷贝使用示例ISerializeServiceserializeServiceIoc.GetServiceISerializeService();// 对象转 JSONMyDatadatanewMyData{NameTest,Value100};stringjsonserializeService.ToJson(data);// JSON 转对象MyDatarestoredserializeService.FromJsonMyData(json);// 对象克隆MyDataclonedserializeService.Clone(data);四、服务使用流程4.1 服务注册在ConfigureServices中注册服务publicpartialclassApp:ApplicationBase{protectedoverridevoidConfigureServices(IServiceCollectionservices){// 注册路径服务services.AddAppPath();// 注册日志服务使用 log4netservices.AddLog4net();// 注册消息服务services.AddAdornerDialogMessage();services.AddSnackMessage();// 注册身份认证服务services.AddIdentity();// 注册设置服务services.AddSetting();// 注册序列化服务services.AddSerialize();}}4.2 服务获取运行时通过 IOC 容器获取服务// 方式一直接获取常用varloggerIoc.GetServiceILogService();// 方式二安全获取不抛异常varoptionalServiceIoc.GetServiceIMyOptionalService(throwIfNone:false);if(optionalService!null){optionalService.DoSomething();}// 方式三静态类访问推荐用于常用服务IocLog.Instance.Info(日志消息);4.3 服务注入在构造函数中注入服务publicclassMyPresenter{privatereadonlyILogService_logService;privatereadonlyIMessageService_messageService;// 通过构造函数注入publicMyPresenter(ILogServicelogService,IMessageServicemessageService){_logServicelogService;_messageServicemessageService;}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);TaskstringGetDataAsync();}步骤2实现服务publicclassMyService:IMyService{publicvoidDoWork(stringparam){// 实现逻辑}publicasyncTaskstringGetDataAsync(){// 异步操作returnawaitTask.FromResult(data);}}步骤3创建扩展方法publicstaticclassMyServiceExtension{publicstaticIServiceCollectionAddMyService(thisIServiceCollectionservices){services.TryAddSingletonIMyService,MyService();returnservices;}}步骤4注册服务protectedoverridevoidConfigureServices(IServiceCollectionservices){services.AddMyService();}6.2 服务配置选项// 定义配置类publicclassMyServiceOptions{publicstringApiUrl{get;set;}http://localhost:5000;publicintTimeout{get;set;}30;}// 扩展方法publicstaticIServiceCollectionAddMyService(thisIServiceCollectionservices,ActionMyServiceOptionssetupActionnull){services.AddOptions();if(setupAction!null)services.Configure(setupAction);services.TryAddSingletonIMyService,MyService();returnservices;}// 使用services.AddMyService(options{options.ApiUrlhttp://api.example.com;options.Timeout60;});七、服务层与其他层的关系┌─────────────────────────────────────────────────────────────┐ │ UI Layer │ │ Controls / Presenters / Views │ ├─────────────────────────────────────────────────────────────┤ │ Modules │ │ 功能模块组合 │ ├─────────────────────────────────────────────────────────────┤ │ Services │ │ 能力提供层 │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Logger │ │ Message │ │ Setting │ │ AppPath │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ ├─────────────────────────────────────────────────────────────┤ │ IOC │ │ 服务连接与管理 │ └─────────────────────────────────────────────────────────────┘调用关系View/Presenter │ ├─→ Ioc.GetServiceIMessageService() │ │ │ ▼ │ MessageService.Show() │ ├─→ Ioc.GetServiceILogService() │ │ │ ▼ │ LogService.Info() │ └─→ Ioc.GetServiceISettingService() │ ▼ SettingService.GetSetting()八、总结服务层是 WPF-Control 框架的能力核心具有以下特点职责清晰每个服务只负责一类能力松耦合通过接口定义便于替换实现可测试依赖注入使单元测试更简单可扩展通过扩展方法轻松添加新服务掌握服务体系的使用是开发高质量 WPF 应用的关键。