BetterLyrics架构揭秘:WinUI 3桌面应用的Core / WinUI3 / Sdk三层分离设计哲学
【免费下载链接】BetterLyrics一款优雅且高度自定义的歌词可视化与全能音乐播放应用,基于 WinUI3/Win2D 构建 | An elegant and deeply customizable lyrics visualizer & versatile music player, built with WinUI3/Win2D项目地址: https://gitcode.com/jayfunc/BetterLyrics
BetterLyrics 是一款基于WinUI 3构建的歌词可视化与全能音乐播放应用。本文以它的源码为例,带你拆解Core、WinUI3、Sdk三个项目如何各司其职,理解现代 Windows 桌面应用最值得借鉴的三层分离架构设计。
一、先看全局:一个解决方案,三个项目
打开解决方案文件 BetterLyrics.slnx,你会发现整个应用只有 3 个 C# 项目 + 1 个打包项目:
| 项目 | 定位 | 目标框架 |
|---|---|---|
BetterLyrics.Sdk | 插件契约层 | net10.0(可发布 NuGet 包) |
BetterLyrics.Core | 业务逻辑层 | net10.0 + Windows 双目标 |
BetterLyrics.WinUI3 | 桌面 UI 层 | net10.0-windows(WinExe 可执行) |
依赖方向是一条清晰单向的链:
BetterLyrics.WinUI3 ──引用──▶ BetterLyrics.Core ──引用──▶ BetterLyrics.Sdk- Sdk 几乎零依赖(只引入了 NLanguageTag),保证任何人拉下来都能秒编译;
- Core 承载全部业务:模型、服务、歌词解析、数据库;
- WinUI3 只负责"长什么样、怎么交互"。
二、Sdk 层:写给插件开发者的"契约"
Sdk 是整个架构里最克制的一层,它只定义接口,不写任何实现:
- 📌 插件入口:IPlugin.cs —— 定义
Title、Version等元数据与InitializeAsync()生命周期钩子; - 📌 能力扩展:
ILyricsSource(歌词搜索)、ILyricsTranslator(翻译)、ILyricsTransliterator(注音/罗马音),一个插件可以同时实现多个; - 📌 宿主能力:IPluginContext.cs 暴露
Localizer、IAIService、IConfigurator,插件可直接调用宿主内置的 AI 与国际化能力; - 📌 零代码配置 UI:PluginBase.cs 通过反射读取配置类属性,用
SettingBuilder自动生成设置界面,插件作者一行 XAML 都不用写。
💡 关键设计:Sdk 是可独立发布的 NuGet 包(含 README.md 与版本兼容表),第三方开发者只装 Sdk 就能开发插件,无需接触整个应用源码。
三、Core 层:平台无关的"业务大脑"
Core 层是代码量最大的一层,但它刻意与 Windows 视觉技术解耦,目录划分非常教科书:
BetterLyrics.Core/ ├── Models/ # 领域模型(歌词、歌曲、设置、统计) ├── Enums/ # 50+ 业务枚举(歌词格式、窗口模式、播放顺序…) ├── Helpers/ # 纯逻辑工具(歌词同步、频谱分析、文件监听) ├── ViewModels/ # MVVM 的 ViewModel(CommunityToolkit.Mvvm) ├── Interfaces/ # Services 接口 + Providers 接口 └── Implementations/Services/ # 20+ 服务的默认实现两个值得注意的细节:
- 双目标框架:Core.csproj 同时构建
net10.0与net10.0-windows,意味着歌词解析、数据库、统计等纯业务逻辑可以在非 Windows 环境编译测试; - 依赖都收敛在这里:SQLite、TagLib(读 ID3)、NAudio(音频)、LiteDB 等 20 多个 NuGet 包全部由 Core 持有,UI 层完全感知不到。
四、WinUI3 层:只做 Windows 该做的事
WinUI3 层承载全部"看得见"的部分:120+ 个 XAML 控件、Shaders 特效(雨雪、流体背景)、Win2D 歌词渲染器,以及 20 个系统钩子(全局热键、IME、任务栏)。
但它做 UI 时从不直接依赖 Core 的具体实现,而是走依赖倒置:
- Core 定义抽象接口,例如 IWindowManagerProvider.cs —— "能开关窗口、设置无边框、固定任务栏进度";
- WinUI3 提供具体实现,例如 WindowManagerProvider.cs,内部调用
WinUIEx、Vanara.PInvoke操作原生 HWND; - Core 的 ViewModel 只认接口,永远不知道自己跑在 WinUI3 上。
这套 Provider 模式把Window、Dispatcher、XAML这些 WinRT 类型彻底挡在 Core 之外——换 UI 框架,Core 一行不改。
五、装配现场:DI 容器把三层"拧"在一起
一切组装都发生在 UI 层的入口 Program.cs 的ConfigureServices()中:
- 服务绑定:
ISettingsService → SettingsService、ILyricsSearchService → LyricsSearchService(Core 的接口与实现配对); - Provider 绑定:
IWindowManagerProvider → WindowManagerProvider(Core 的接口配 WinUI3 的实现); - 全部 ViewModel 注册为单例,供任意窗口即取即用。
这个文件是理解整个项目的最佳"目录索引":注册表里列了什么,这个应用就有什么能力。
六、三层分离带来了什么?
- ✅插件生态:Sdk 独立发版,插件开发者零成本接入,宿主更新有明确兼容版本表;
- ✅可测试性:Core 无 UI 依赖,业务逻辑可脱离窗口做单元测试;
- ✅职责清晰:新增一个桌面歌词特效只动 WinUI3,新增一个歌词源只动 Core/Sdk,互不干扰;
- ✅面向未来:若要做 MAUI 或 Web 端歌词服务,Core 的
net10.0目标已经是现成的起点。
七、延伸阅读:模块路径速查
| 想了解 | 去哪里 |
|---|---|
| 插件开发规范 | Sdk README |
| 歌词同步/解析算法 | Helpers/Lyrics |
| 服务接口清单 | Interfaces/Services |
| 平台抽象接口 | Interfaces/Providers |
| 用户指南 | USER_GUIDE.CN.md |
三层分离不是为了炫技,而是让"业务、界面、生态"三条演进线彼此独立——这正是 BetterLyrics 能从单文件歌词工具长成一个完整音乐生态的核心原因。
【免费下载链接】BetterLyrics一款优雅且高度自定义的歌词可视化与全能音乐播放应用,基于 WinUI3/Win2D 构建 | An elegant and deeply customizable lyrics visualizer & versatile music player, built with WinUI3/Win2D项目地址: https://gitcode.com/jayfunc/BetterLyrics
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考