Avalonia支持插件化架构,通过动态加载程序集、反射和DataTemplate/ViewLocator实现运行时View切换;核心依赖统一接口(如IPlugin、IViewProvider)、松耦合容器及约定而非编译期引用。
Avalonia 支持通过动态加载程序集(Assembly)+ 反射 + 数据模板(DataTemplate)或视图定位器(ViewLocator)机制,实现插件化架构和运行时切换不同 View。核心不依赖编译期硬引用,而是靠约定、接口抽象与松耦合容器管理。
所有插件需实现同一组基础接口,例如:
Type),或直接返回已实例化的 IControl
插件项目引用 Avalonia.Core 和你的公共契约库(如 MyApp.Contracts),但不引用主程序 UI 层。
在主程序中(如 App.xaml.cs 或 MainWindow 中),用 AssemblyLoadContext 安全加载插件 DLL:
AssemblyLoadContext.LoadFromAssemblyPath(path) 加载插件assembly.GetTypes().Where(t => t.IsClass && !t.IsAbstract && typeof(IViewProvider).IsAssignableFrom(t))
IViewProvider 实例(支持带参构造或无参 + 属性注入)(pluginId, viewProvider) 映射,供后续按需获取 View 类型⚠️ 注意:Avalonia 的 XAML 编译器(AvaloniaXamlLoader)默认只认当前程序集中的类型。若插件含自定义 XAML View,需提前调用 AvaloniaRuntimeXamlLoader.Load 或启用 CompileWithAvaloniaXaml 并确保插件项目正确配置生成 .axaml.g.cs。
推荐两种主流方式:
PluginAViewModel : IPluginViewModel),在主窗口资源中注册 DataTemplate,绑定 ContentControl.Content 到当前 ViewModel。Avalonia 自动匹配模板并渲染对应 ViewviewProvider.CreateView() 得到 IControl,再设为 ContentControl.Content。适合需要精细控制生命周期的场景(注意手动处理 DataContext 和资源释放)若做导航系统(类似 Prism),可封装 IViewStack 或继承 ContentControl 实现自己的 PluginHostControl,支持路由参数、后退栈、激活/停用通知。
标准 .NET 不支持卸载已加载的 Assem
bly,但可通过 AssemblyLoadContext 创建隔离上下文实现有限卸载:
AssemblyLoadContext(isCollectible: true)DefaultContext 共享基础类型)context.UnloadAsync() 卸载插件 —— 此时需确保无强引用(如事件未解绑、静态缓存未清理)实践中更常见的是“重启插件”而非真正卸载:重新加载新版本 DLL,替换旧 provider 实例,并触发界面刷新。
基本上就这些。关键在于接口先行、弱引用加载、ViewModel 或类型驱动渲染,再配合合理的生命周期管理。不复杂但容易忽略 XAML 类型解析和 Assembly 卸载限制。