一个基于 CommunityToolkit.Mvvm 的源生成器项目,自动生成 ViewModel 绑定代码,简化 MVVM 模式的实现。
- 自动 ViewModel 绑定: 通过
[AutoViewModel]
特性自动生成绑定代码 - 依赖注入支持: 完整集成 CommunityToolkit.Mvvm 的 IoC 容器
- 智能类型处理: 自动识别 Window 类型并智能处理 DataContext 设置
- 类型安全: 编译时类型检查,避免运行时错误
- 灵活配置: 支持多种配置选项满足不同需求
在你的 View 类上添加 [AutoViewModel]
特性:
using MvvmTooklit.Attributes;
using SourceGeneratorExample.ViewModels;
[AutoViewModel(typeof(MainPageViewModel))]
public sealed partial class MainPage : Page
{
public MainPage()
{
InitializeComponent();
InitializeViewModel(); // 自动生成的方法
}
}
在 App.xaml.cs
中配置 IoC 容器:
private void ConfigureServices()
{
var services = new ServiceCollection();
// 注册服务
services.AddSingleton<IUserService, UserService>();
// 注册 ViewModels
services.AddTransient<MainPageViewModel>();
services.AddTransient<MainWindowViewModel>();
// 配置 CommunityToolkit.Mvvm 的 IoC 容器
var serviceProvider = services.BuildServiceProvider();
Ioc.Default.ConfigureServices(serviceProvider);
}
public partial class MainPageViewModel : ObservableObject
{
private readonly IUserService _userService;
public MainPageViewModel(IUserService userService)
{
_userService = userService;
// 初始化逻辑...
}
}
AutoViewModelAttribute
支持以下配置选项:
[AutoViewModel(typeof(MyViewModel),
PropertyName = "MyViewModel", // ViewModel 属性名(默认:"ViewModel")
SetDataContext = false, // 是否自动设置 DataContext(默认:true)
ResolveFromContainer = false)] // 是否从容器解析(默认:true)
public partial class MyView : Page
{
// ...
}
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
PropertyName |
string |
"ViewModel" |
生成的 ViewModel 属性名称 |
SetDataContext |
bool |
true |
是否自动设置 DataContext(Window 类型会自动忽略) |
ResolveFromContainer |
bool |
true |
是否从 DI 容器解析 ViewModel |
// 生成的代码
ViewModel = Ioc.Default.GetService<MyViewModel>();
优势:
- 支持构造函数依赖注入
- 遵循 MVVM 最佳实践
- 适合复杂应用架构
// 生成的代码
ViewModel = Activator.CreateInstance<MyViewModel>();
优势:
- 简单直接,无需配置 DI
- 适合简单的 ViewModel
- 减少外部依赖
SourceGeneratorExample/
├── MvvmTooklit/ # 核心库
│ ├── Attributes/
│ │ └── AutoViewModelAttribute.cs
│ └── Services/
│ └── ServiceLocator.cs
├── MvvmTooklit.Gen/ # 源生成器
│ └── Generators/
│ └── ViewModelAutoBindGenerator.cs
└── SourceGeneratorExample/ # 示例应用
├── ViewModels/
│ ├── MainPageViewModel.cs
│ └── MainWindowViewModel.cs
└── Views/
├── MainPage.xaml
├── MainPage.xaml.cs
├── MainWindow.xaml
└── MainWindow.xaml.cs
[AutoViewModel(typeof(MainWindowViewModel))]
public sealed partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InitializeViewModel();
// Window 类型不会自动设置 DataContext
// 需要手动设置子元素的 DataContext
}
}
[AutoViewModel(typeof(MainPageViewModel))]
public sealed partial class MainPage : Page
{
public MainPage()
{
InitializeComponent();
InitializeViewModel();
// 自动设置 this.DataContext = ViewModel
}
}
[AutoViewModel(typeof(CustomViewModel),
PropertyName = "MyViewModel",
SetDataContext = false,
ResolveFromContainer = false)]
public sealed partial class CustomView : UserControl
{
public CustomView()
{
InitializeComponent();
InitializeViewModel();
// 手动设置 DataContext
this.DataContext = MyViewModel;
}
}
-
克隆项目
git clone <repository-url> cd SourceGeneratorExample
-
打开解决方案
- 使用 Visual Studio 2022 打开
SourceGeneratorExample.sln
- 使用 Visual Studio 2022 打开
-
构建项目
- 构建解决方案 (Ctrl+Shift+B)
- 源生成器会自动生成绑定代码
-
运行示例
- 设置
SourceGeneratorExample
为启动项目 - 按 F5 运行
- 设置
确保已安装 .NET Compiler Platform SDK。
项目已预配置了调试所需的设置,可以直接进行调试:
-
配置调试启动配置文件
- 右键点击
MvvmTooklit.Gen
项目 - 选择 Properties(属性)
- 点击 Debug(调试)
- 点击 Open debug launch profiles UI(打开调试启动配置文件 UI)
- 右键点击
-
添加 Roslyn 组件调试配置
- 如果已有配置文件,点击 Delete(删除) 删除现有配置
- 点击 Add(添加)
- 选择 Roslyn component
- 在 Target project(目标项目) 中选择
SourceGeneratorExample
- 关闭 UI
-
重启 Visual Studio
- 关闭并重新启动 Visual Studio 2022
- 重新打开解决方案
-
开始调试
- 在调试配置文件下拉菜单中选择
MvvmTooklit.Gen
项目 - 在源生成器代码中设置断点(如
ViewModelAutoBindGenerator.cs
) - 点击 Play(播放) 按钮开始调试
- 在调试配置文件下拉菜单中选择
-
设置断点位置
// 在 ViewModelAutoBindGenerator.cs 中的关键方法设置断点 private static void Execute(Compilation compilation, ImmutableArray<ViewInfo?> views, SourceProductionContext context) { // 在这里设置断点 👈 foreach (var viewInfo in views) { // ... } }
-
查看生成的代码
- 生成的文件位于:
MvvmTooklit.Gen/Generated/
目录 - 也可以在 Solution Explorer 中展开项目节点查看生成的文件
- 生成的文件位于:
-
调试输出
// 在源生成器中添加调试输出 System.Diagnostics.Debug.WriteLine($"Processing view: {viewInfo.ViewSymbol.Name}");
- 在源生成器中设置断点
- 启动调试 (F5)
- Visual Studio 会:
- 启动新的 VS 实例
- 加载目标项目 (
SourceGeneratorExample
) - 触发源生成器执行
- 在断点处暂停
项目已预配置了调试所需的设置:
MvvmTooklit.Gen.csproj:
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsRoslynComponent>true</IsRoslynComponent>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
SourceGeneratorExample.csproj:
<ProjectReference
Include="..\MvvmTooklit.Gen\MvvmTooklit.Gen.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false"/>
- .NET 8.0
- WinUI 3
- CommunityToolkit.Mvvm
- Microsoft.CodeAnalysis
- 源生成器技术
- Visual Studio 2022 17.0+
- .NET 8.0 SDK
- Windows 10 版本 1809 (Build 17763) 或更高版本
欢迎提交 Issue 和 Pull Request 来改进这个项目!
本项目基于 MIT 许可证开源。