本文围绕 MVVMLight 与 CommunityToolkit.Mvvm 的演进脉络、核心对比、实操差异及迁移指南 展开,帮助开发者快速完成技术选型与项目升级。
在 WPF、UWP、MAUI、WinUI 3 等 XAML 技术体系中,MVVM 是实现界面与业务逻辑解耦的核心架构模式。
提到 MVVM 框架,开发者通常会经历这样一个认知路径:
- 经典方案:MVVMLight
- 现代标准:CommunityToolkit.Mvvm
随着 .NET 进入统一平台时代(.NET Core / .NET 5+),MVVMLight 逐渐退出主流舞台,而 CommunityToolkit.Mvvm 成为官方推荐方案。
一、历史渊源:从个人开源到微软官方
1.1 MVVMLight:开源时代的经典之作
创始人:Laurent Bugnion
📅 发展阶段
- 2009:发布 MVVM Light Toolkit
- 2011--2018:支持 WPF / Silverlight / Windows Phone / Xamarin
- 后期:进入维护模式(Legacy)
🎯 设计理念
- 轻量
- 无侵入
- 只做核心(ViewModel / Command / Messenger)
⚠️ 当前状态:
- ✔ 可运行于 .NET Core / .NET 5+(基于 .NET Standard)
- ❌ 不再积极维护
- ❌ 不支持 AOT / 源生成器
- ⚠️ 已进入历史阶段
1.2 CommunityToolkit.Mvvm:现代 .NET 标准答案
核心开发者:Sergio Pedri + 微软团队
📅 发展阶段
- 2020.04:项目启动(受 MVVMLight 启发,并提供迁移指导)
- 2020:项目启动(Windows Community Toolkit 内)
- 2021:v7.0 发布(更名为 CommunityToolkit.Mvvm 并加入 .NET 基金会)
- 2022 :8.0 引入源码生成器
- 2024+:支持 .NET 9 + NativeAOT
🤝 与 MVVMLight 的关系
官方说明:该库受 MVVMLight 启发,并与 Laurent 共同制定迁移路径。
👉 关键结论:
- ❌ 不是 Laurent 创建
- ✅ 微软主导开发
- ✅ 面向现代 .NET
1.3 核心演进总结
| 维度 | 演进方向 |
|---|---|
| 维护模式 | 个人 → 官方 |
| 技术架构 | MVVMLight:运行时机制(基于 INotifyPropertyChanged + 反射/手写实现)CommunityToolkit.Mvvm:编译期源生成器(Source Generator) |
| 性能 | 运行时 → 编译时 |
| 平台 | 单一 → 全平台 |
| 功能 | 基础 → 现代化 |
二、核心维度对比
| 对比维度 | MVVMLight | CommunityToolkit.Mvvm |
|---|---|---|
| 创始人 | Laurent Bugnion | 微软团队 |
| 项目性质 | 个人开源 | 官方工具包 |
| 维护状态 | ⚠️ Legacy | ✅ 活跃 |
| 技术架构 | 反射 | 源生成器 |
| 性能 | MVVMLight:运行时绑定 + 手动通知机制 | CommunityToolkit.Mvvm:编译期生成,减少运行时开销 |
| 异步命令支持 | ❌(需手动封装) | ✅(原生支持 IAsyncRelayCommand) |
| AOT 支持 | ❌ | ✅ |
| 代码生成 | ❌ | ✅ |
三、核心功能实操对比(注释增强版)
3.1 ViewModel 实现
MVVMLight(传统写法)
csharp
using GalaSoft.MvvmLight;
// 继承 ViewModelBase(内部实现 INotifyPropertyChanged)
public class MainViewModel : ViewModelBase
{
// ① 手动字段
private string _userName;
// ② 手动属性
public string UserName
{
get => _userName;
// ③ 调用 Set 触发通知
set => Set(ref _userName, value);
/*
* Set 做了:
* 1. 判断值是否变化
* 2. 更新字段
* 3. 触发 PropertyChanged
*/
}
}
📌 缺点:
- 手写属性
- 强依赖基类
- 样板代码多
CommunityToolkit.Mvvm(现代写法)
csharp
using CommunityToolkit.Mvvm.ComponentModel;
// 必须 partial(源码生成器需要)
public partial class MainViewModel : ObservableObject
{
// 自动生成属性
[ObservableProperty]
private string _userName;
/*
* 自动生成:
* public string UserName
* {
* get => _userName;
* set => SetProperty(ref _userName, value);
* }
*/
}
📌 优势:
- 零样板代码
- 编译期生成
- 支持 AOT
3.2 命令绑定
MVVMLight(手动命令)
csharp
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
public class MainViewModel : ViewModelBase
{
// ICommand 属性
public ICommand SubmitCommand { get; }
public MainViewModel()
{
// 手动绑定
SubmitCommand = new RelayCommand(ExecuteSubmit);
}
// 执行逻辑
private void ExecuteSubmit()
{
Console.WriteLine("执行提交");
}
}
📌 问题:
- 手动 new
- 不支持 async
CommunityToolkit.Mvvm(自动命令)
csharp
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
public partial class MainViewModel : ObservableObject
{
// 自动生成 SubmitCommand
[RelayCommand]
private void Submit()
{
Console.WriteLine("同步执行");
}
/*
* 自动生成:
* public ICommand SubmitCommand { get; }
*/
// 自动生成 AsyncSubmitCommand
[RelayCommand]
private async Task AsyncSubmit()
{
await Task.Delay(1000);
Console.WriteLine("异步完成");
}
/*
* 自动生成:
* public IAsyncRelayCommand AsyncSubmitCommand { get; }
*/
}
📌 优势:
- 方法即命令
- 原生 async
- 更简洁
3.3 消息通信
MVVMLight(强引用)
csharp
using GalaSoft.MvvmLight.Messaging;
// 发送
Messenger.Default.Send("测试消息");
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
// 注册(强引用)
Messenger.Default.Register<string>(this, msg =>
{
Console.WriteLine(msg);
});
/*
* ⚠️ 强引用问题:
* 未及时 Unregister 时,在复杂生命周期场景下可能导致内存泄漏
*/
}
// 必须手动释放
public void Cleanup()
{
Messenger.Default.Unregister(this);
}
}
CommunityToolkit.Mvvm(弱引用)
csharp
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
// 发送
WeakReferenceMessenger.Default.Send("测试消息");
public partial class MainViewModel : ObservableObject
{
public MainViewModel()
{
// 注册(弱引用)
WeakReferenceMessenger.Default.Register<string>(this, (r, msg) =>
{
Console.WriteLine(msg);
});
/*
* ✔ 自动释放
* ✔ 无需 Unregister
*/
}
}
📌 优势:
- 弱引用(避免内存泄漏)
- 自动管理生命周期
- API 更现代化
四、技术选型建议(非常重要)
🎯 新项目
👉 直接选择:
✅ CommunityToolkit.Mvvm
❌ 不建议使用 MVVMLight 的原因
- 已停止演进
- 不支持现代 .NET
- 不支持 AOT
- 存在内存风险
✅ CommunityToolkit.Mvvm 核心价值
- 微软官方维护
- 高性能(零反射)
- 支持 MAUI / WinUI / WPF
- 极致减少代码量
五、迁移指南(精华)
| MVVMLight | CommunityToolkit |
|---|---|
| ViewModelBase | ObservableObject |
| Set() | [ObservableProperty] |
| RelayCommand | [RelayCommand] |
| Messenger | WeakReferenceMessenger |
六、一句话总结
MVVMLight 是"过去的最佳实践",而 CommunityToolkit.Mvvm 是"当前与未来的标准答案"。
七、结尾(建议保留)
如果你正在维护老项目:
- ✅ 可以继续使用 MVVMLight(稳定即可)
- 🚀 新功能建议逐步迁移
如果你在做新项目:
不要再犹豫,直接使用 CommunityToolkit.Mvvm。
👋 关注我!持续分享 C# 实战技巧、代码示例 & 技术干货