
AI 技能AI 插件【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,400 agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址https://gitcode.com/gh_mirrors/an/agentic-awesome-skills点击查看免费下载本文围绕 AAS 仓库中avalonia-viewmodels-zafiro技能的《Composition Mapping》指南系统讲解如何在 Avalonia 应用中借助 Zafiro 工具链与 ReactiveUI将 ViewModel 正确实例化并映射到对应 View从DataTypeViewLocator的数据模板注册、CompositionRoot的依赖注入容器搭建到OnFrameworkInitializationCompleted中的视图注入以及命令、导航、Section 自动发现与 Wizard 流等配套模式的组合运用。读者读完后将能独立搭建一套可维护、可测试、支持依赖注入的 Avalonia MVVM 应用骨架并理解其底层映射与解析原理。概述为什么组合与映射决定应用的可维护性在基于 Zafiro 与 ReactiveUI 的 Avalonia 应用中如何把 ViewModel 正确实例化并映射到对应的 View是应用长期可维护的关键。如果映射靠手写 switch 分支、实例化靠new满天飞那么每新增一个页面都要改动多处代码测试也会寸步难行。Zafiro 给出的答案是两条清晰的主线视图定位View Location通过DataTypeViewLocator根据 ViewModel 的数据类型自动解析对应 View配合 Avalonia 的DataTemplates在 XAML 中声明式完成映射组合根Composition Root在一个集中的CompositionRoot中完成依赖注入DI与服务注册View 与 ViewModel 都不再自己new依赖而是由容器统一装配。本技能SKILL.md将这一套最佳实践总结为五项核心原则函数式响应式状态管理ReactiveUI、增强命令IEnhancedCommand、声明式 Wizard 流程SlimWizard、Section 自动发现[Section]特性、以及本文重点的干净组合与映射。以下逐步展开。ViewModel-to-View 映射DataTypeViewLocator的声明式装配Zafiro 使用DataTypeViewLocator根据 ViewModel 的数据类型自动把 ViewModel 映射到对应的 View。它的核心思想是当某个数据对象这里是 ViewModel被绑定到ContentControl等内容宿主时Avalonia 会通过应用级DataTemplates查找能处理该类型的模板DataTypeViewLocator正是这样一个以类型为键的数据模板解析器——只要在程序集里按约定为每个 ViewModel 定义对应的 View映射就自动成立无需为每个页面手写模板。在 App.axaml 中集成在应用的全局资源中注册DataTypeViewLocator并引入 Zafiro 预置的数据模板Application.DataTemplates DataTypeViewLocator / DataTemplateInclude Sourceavares://Zafiro.Avalonia/DataTemplates.axaml / /Application.DataTemplates要点说明DataTypeViewLocator /作为应用级数据模板注册后ContentControl绑定任何已注册类型的 ViewModel 时都会自动解析出对应 ViewDataTemplateInclude Sourceavares://Zafiro.Avalonia/DataTemplates.axaml通过 Avalonia 的avares://资源协议引用 Zafiro.Avalonia 程序集内建的数据模板控件模板、基础模板等保证 Zafiro 控件体系的基本模板可用Application.DataTemplates是 Avalonia 3.x 的新资源节点对应旧版DataTemplates资源字典对全局模板生效。注册方式命名约定与源生成器映射的注册既可以是全局的也可以是局部的。Zafiro 项目中的常见实践有两种命名约定为每个FooViewModel提供同名FooView由DataTypeViewLocator通过反射或约定规则完成解析新增页面零配置显式注册源生成器通过源生成器Source Generator扫描程序集为每个 ViewModel 生成ViewForFooViewModel()之类的注册代码把类型 → View的映射表在编译期确定兼具性能与可追溯性。从技能指南的结构看这一机制与 navigation_sections.md 中基于[Section]特性的自动注册形成呼应Section ViewModel 同样可以被容器自动收集并注册再经由同样的 View 定位机制渲染到宿主控件中。CompositionRoot集中管理依赖注入与服务注册组合根是应用唯一知道所有依赖的地方。Zafiro 项目建议使用一个中心的CompositionRoot静态类把依赖注入容器的搭建、服务的注册、根 ViewModel 的创建都收敛到一处避免依赖关系散落在各 ViewModel 的构造函数里。public static class CompositionRoot { public static IShellViewModel CreateMainViewModel(Control topLevelView) { var services new ServiceCollection(); services .AddViewModels() .AddUIServices(topLevelView); var serviceProvider services.BuildServiceProvider(); return serviceProvider.GetRequiredServiceIShellViewModel(); } }这段代码的职责拆解ServiceCollection来自 Microsoft.Extensions.DependencyInjection是标准 .NET 容器Zafiro 项目直接复用它不引入额外 IoC 框架AddViewModels()是扩展方法负责注册全部 ViewModel见下一节AddUIServices(topLevelView)负责注册 UI 相关服务例如把顶层控件Control传入供NotificationService等需要锚定到可视树的服务使用容器构建完成后通过GetRequiredServiceIShellViewModel()解析出根 ViewModel——注意这里解析的是接口具体实现由容器决定这正是依赖注入带来的解耦收益。注册 ViewModel选择正确的生命周期作用域ViewModel 通过扩展方法集中注册并按使用场景选择生命周期作用域Scopepublic static IServiceCollection AddViewModels(this IServiceCollection services) { return services .AddTransientIHomeSectionViewModel, HomeSectionSectionViewModel() .AddSingletonIShellViewModel, ShellViewModel(); }三种作用域的选取原则作用域语义适用场景AddTransient每次解析都新建实例表单页、向导步骤等一次性页面 ViewModelAddScoped同一作用域内共享实例按请求/会话划分的 ViewModel 组AddSingleton全局唯一实例Shell 主窗口、全局状态、长期存活的服务在示例中ShellViewModel作为应用外壳常驻注册为单例IHomeSectionViewModel这类页面级 ViewModel 使用 Transient每次进入页面都能拿到全新实例避免状态串扰。若 ViewModel 依赖 UI 服务如通知、导航器务必通过构造函数注入而非服务定位器Service Locator反模式获取。View Injection在应用启动时完成视图与视图模型的连接OnFrameworkInitializationCompleted是 Avalonia 生命周期钩子中完成根视图装配的标准位置。Zafiro 的Connect辅助方法若可用允许把视图工厂、ViewModel 工厂与窗口工厂声明式地组合在一起public override void OnFrameworkInitializationCompleted() { this.Connect( () new ShellView(), view CompositionRoot.CreateMainViewModel(view), () new MainWindow()); base.OnFrameworkInitializationCompleted(); }Connect的三个参数分别描述视图工厂() new ShellView()创建根视图ShellViewViewModel 工厂view CompositionRoot.CreateMainViewModel(view)以该视图为参数调用组合根得到IShellViewModel——注意视图实例被传入组合根以便AddUIServices(topLevelView)注册 UI 服务时能锚定到真实可视树窗口工厂() new MainWindow()创建承载以上内容的顶层窗口。连接完成后再调用base.OnFrameworkInitializationCompleted()确保框架默认初始化逻辑例如桌面应用的标准生命周期处理正常执行。手动实例化但有依赖用ActivatorUtilities.CreateInstance[!TIP] 当需要手动实例化一个类、同时又希望其构造函数依赖能从IServiceProvider解析时使用ActivatorUtilities.CreateInstance。例如var vm ActivatorUtilities.CreateInstanceMyViewModel(serviceProvider, arg1, arg2);它允许在构造函数参数列表中混入容器解析的依赖与调用方传入的实参非常适合在模板工厂、运行时动态创建等场景下保留 DI 的一致性避免绕过容器导致依赖链断裂。配套模式让组合后的 ViewModel 真正可用组合与映射解决的是装配问题而装配出来的 ViewModel 要真正好用还需配合本技能族avalonia-viewmodels-zafiro中的几个核心模式。这些模式与CompositionRoot中的注册、DataTypeViewLocator中的映射互为表里共同构成完整的 MVVM 实践。函数式响应式 ViewModelReactiveObject[Reactive]ViewModel 以ReactiveObject为基类属性用 ReactiveUI.SourceGenerators 的[Reactive]特性声明自动生成可观察属性再用WhenAnyValue响应式地派生状态详见 viewmodels.mdpublic partial class MyViewModel : ReactiveObject { [Reactive] private string name; [Reactive] private bool isBusy; } // 属性变化 → 派生状态 this.WhenAnyValue(x x.Name) .Select(name !string.IsNullOrEmpty(name)) .ToPropertyEx(this, x x.CanSubmit);增强命令IEnhancedCommand与错误管道命令使用ReactiveCommand.Create/CreateFromTask创建后通过Enhance()附加Text、Name等元数据错误处理通过HandleErrorsWith统一导向NotificationService替代散落的手写Subscribepublic IEnhancedCommand Submit { get; } Submit ReactiveCommand.CreateFromTask(OnSubmit, canSubmit) .Enhance(text: Submit Data, name: SubmitCommand); Submit.HandleErrorsWith(uiServices.NotificationService, Submission Failed) .DisposeWith(disposable);HandleErrorsWith把命令异常自动封装为用户可见的提示如 Submission Failed并在订阅生命周期内随CompositeDisposable释放patterns.md 中强调这是替代手动Subscribe的统一错误管道。导航与 Section 自动发现导航通过INavigator接口完成navigation_sections.mdpublic async Task GoToDetails() { await navigator.Navigate(() new DetailsViewModel()); }模块化 UI标签页、侧边栏项用[Section]特性标注并在组合根中自动注册[Section(Wallet, icon: fa-wallet)] public class WalletSectionViewModel : IWalletSectionViewModel { } // 在 CompositionRoot 中 services.AddAnnotatedSections(logger); services.AddSectionsFromAttributes(logger); // 切换当前 Section shellViewModel.SetSection(Browse);icon参数支持 FontAwesome 图标如fa-home前提是配置了ProjektankerIconControlProvider。这套机制与AddViewModels()的显式注册形成互补显式注册保底特性扫描自动扩展新增 Section 时无需改动组合根代码。Wizard 流程SlimWizard的声明式多步导航复杂多步流程使用SlimWizardWizardBuilder声明式定义wizards.mdSlimWizardstring wizard WizardBuilder .StartWith(() new Step1ViewModel(data)) .NextUnit() .WhenValid() .Then(prevResult new Step2ViewModel(prevResult)) .NextCommand(vm vm.CustomNextCommand) .Then(result new SuccessViewModel(Done!)) .Next((_, s) s, Finish) .WithCompletionFinalStep(); var result await wizard.Navigate(navigator);导航规则NextUnit()、NextCommand()、WhenValid()、Always()与最终步配置WithCompletionFinalStep()/WithCommitFinalStep()由构建器链式表达Back 命令由SlimWizard自动处理保证各流程体验一致。Wizard 步骤 ViewModel 同样遵循构造函数注入数据、依赖由容器装配的原则与CompositionRoot无缝衔接。综合实战一个最小可运行的应用装配骨架综合以上各节一个完整的 Zafiro 风格 Avalonia 应用启动装配流程如下App.axaml注册DataTypeViewLocator与 Zafiro 数据模板CompositionRootCreateMainViewModel(topLevelView)中构建容器、注册 ViewModel 与 UI 服务、解析IShellViewModelApp.axaml.cs在OnFrameworkInitializationCompleted中用Connect或手动实例化 ActivatorUtilities.CreateInstance连接ShellView、ShellViewModel与MainWindow运行时任意位置绑定 ViewModel 到ContentControl由DataTypeViewLocator自动解析对应 View导航用INavigatorSection 由[Section]自动注册并切换复杂流程用SlimWizard承载。public override void OnFrameworkInitializationCompleted() { this.Connect( () new ShellView(), view CompositionRoot.CreateMainViewModel(view), () new MainWindow()); base.OnFrameworkInitializationCompleted(); }值得强调的是View 层应保持轻薄布局与视觉交给 Zafiro.Avalonia 的语义容器与共享样式见 avalonia-layout-zafiro 中的EdgePanel、HeaderedContainer等组件以及 components.md 的通用组件拆分原则View 内不写业务逻辑不手动new依赖——所有装配责任收敛到CompositionRoot与 View 定位器这正是组合与映射模式对应用可维护性的最终承诺。适用前提与注意事项本文示例基于 Zafiro / Zafiro.Avalonia 工具链与 ReactiveUI含ReactiveUI.SourceGenerators使用时请确保项目已引用相应 NuGet 包并配置了源生成器Connect辅助方法、AddAnnotatedSections/AddSectionsFromAttributes、Enhance()等 API 的具体签名以所引用 Zafiro 版本为准示例代码展示了其调用形态技能指南明确提示SKILL.md本技能仅适用于其描述范围内的任务输出不应替代针对具体环境的验证、测试与专家评审若缺少必要输入、权限、安全边界或成功标准应停下并澄清需求。输出文章赞分享AI 技能AI 插件【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,400 agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址https://gitcode.com/gh_mirrors/an/agentic-awesome-skills点击查看免费下载相关推荐TKEStack插件生态详解Galaxy网络与GPU管理的应用指南TKEStack插件生态详解Galaxy网络与GPU管理的应用指南 TKEStack是一款原生Kubernetes容器管理平台支持多租户和多集群管理。其强大Instant-NuRecNVIDIA革命性3D高斯溅射技术2分钟快速重建自动驾驶场景Instant NuRecNVIDIA革命性3D高斯溅射技术2分钟快速重建自动驾驶场景 Instant NuRec是NVIDIA推出的革命性3D高斯溅射技术人工智能计算机视觉自动驾驶Mosby3与依赖注入框架整合Dagger2与Koin实战Mosby3与依赖注入框架整合Dagger2与Koin实战 想要构建一个 现代化Android应用架构 吗 Mosby3 作为一款强大的Model View移动开发创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考