1. Prism框架简介
Prism是一个用于构建松散耦合、可测试和可维护的WPF桌面应用程序的框架。它最初由微软模式与实践团队开发,现在由社区维护,是构建企业级WPF应用程序的首选框架之一。
Prism框架的核心优势:
- 模块化设计:将应用程序分解为独立的功能模块
- 松散耦合:通过依赖注入和事件聚合器实现组件间的松散耦合
- MVVM模式支持:提供完整的MVVM(Model-View-ViewModel)实现
- 导航框架:简化视图间的导航
- 区域管理:支持动态UI组合
- 命令模式:提供强大的命令绑定机制
2. Prism核心组件
2.1 模块化系统
Prism的模块化系统允许开发人员将应用程序分解为独立的功能模块,每个模块可以单独开发、测试和部署。
// 模块定义示例
public class CustomerModule : IModule
{private readonly IRegionManager _regionManager;public CustomerModule(IRegionManager regionManager){_regionManager = regionManager;}public void OnInitialized(IContainerProvider containerProvider){// 在区域中注册视图_regionManager.RegisterViewWithRegion("MainRegion", typeof(CustomerView));}public void RegisterTypes(IContainerRegistry containerRegistry){// 注册服务和视图containerRegistry.RegisterSingleton<ICustomerService, CustomerService>();containerRegistry.RegisterForNavigation<CustomerDetailView>();}
}
2.2 依赖注入容器
Prism支持多种依赖注入容器,包括Unity、DryIoc和Autofac。依赖注入是实现松散耦合的关键机制。
// 应用程序启动配置
protected override void ConfigureContainer()
{// 注册类型到DI容器Container.RegisterType<IOrderService, OrderService>(new ContainerControlledLifetimeManager());Container.RegisterType<ICustomerRepository, CustomerRepository>();
}
2.3 区域管理器
区域管理器允许在预定义的UI区域中动态加载和卸载视图,是实现模块化UI的核心组件。
// 在XAML中定义区域
<ContentControl prism:RegionManager.RegionName="MainRegion" />// 在代码中导航到区域
_regionManager.RequestNavigate("MainRegion", "CustomerView");
2.4 事件聚合器
事件聚合器提供了一种发布-订阅机制,允许模块之间进行通信而无需直接引用。
// 定义事件
public class CustomerUpdatedEvent : PubSubEvent<CustomerModel> { }// 发布事件
_eventAggregator.GetEvent<CustomerUpdatedEvent>().Publish(updatedCustomer);// 订阅事件
_eventAggregator.GetEvent<CustomerUpdatedEvent>().Subscribe(OnCustomerUpdated, ThreadOption.UIThread, false, customer => customer.Id == currentCustomerId);
3. MVVM模式实现
Prism提供了完整的MVVM实现,包括BindableBase基类、DelegateCommand和导航服务。
3.1 BindableBase
BindableBase类实现了INotifyPropertyChanged接口,简化了属性变更通知。
public class CustomerViewModel : BindableBase
{private string _name;public string Name{get => _name;set => SetProperty(ref _name, value);}private bool _isActive;public bool IsActive{get => _isActive;set => SetProperty(ref _isActive, value, () => RaisePropertyChanged(nameof(StatusDisplay)));}public string StatusDisplay => IsActive ? "活跃" : "非活跃";
}
3.2 DelegateCommand
DelegateCommand提供了命令模式的实现,支持命令执行条件和命令状态更新。
public class OrderViewModel : BindableBase
{private readonly IOrderService _orderService;private Order _currentOrder;public DelegateCommand SubmitOrderCommand { get; private set; }public OrderViewModel(IOrderService orderService){_orderService = orderService;SubmitOrderCommand = new DelegateCommand(ExecuteSubmitOrder, CanSubmitOrder).ObservesProperty(() => CurrentOrder.IsValid);}private bool CanSubmitOrder(){return CurrentOrder != null && CurrentOrder.IsValid;}private void ExecuteSubmitOrder(){_orderService.SubmitOrder(CurrentOrder);}public Order CurrentOrder{get => _currentOrder;set => SetProperty(ref _currentOrder, value);}
}
4. 导航框架
Prism的导航框架简化了视图之间的导航,支持导航参数和导航回调。
// 注册导航
containerRegistry.RegisterForNavigation<ProductDetailView>("ProductDetail");// 执行导航
_navigationService.NavigateAsync("ProductDetail?id=123", new NavigationParameters{{ "category", "electronics" }});// 在目标ViewModel中接收参数
public override void OnNavigatedTo(INavigationParameters parameters)
{if (parameters.ContainsKey("id")){string productId = parameters.GetValue<string>("id");LoadProduct(productId);}
}
5. 对话框服务
Prism提供了对话框服务,用于显示模态和非模态对话框。
// 注册对话框
containerRegistry.RegisterDialog<ConfirmationDialog, ConfirmationDialogViewModel>();// 显示对话框
_dialogService.ShowDialog("ConfirmationDialog", new DialogParameters{{ "title", "确认删除" },{ "message", "确定要删除此项目吗?" }}, r =>{if (r.Result == ButtonResult.OK){DeleteItem();}});
6. 实际应用示例
下面是一个简单的Prism应用程序结构示例:
MyPrismApp/
├── MyPrismApp.Core/ # 核心库,包含共享接口和模型
├── MyPrismApp.Modules.Orders/ # 订单模块
├── MyPrismApp.Modules.Customers/ # 客户模块
├── MyPrismApp.Modules.Products/ # 产品模块
└── MyPrismApp/ # 主应用程序├── App.xaml├── App.xaml.cs└── Shell.xaml # 主窗口
6.1 应用程序启动类
public partial class App : PrismApplication
{protected override Window CreateShell(){return Container.Resolve<Shell>();}protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterSingleton<IApplicationSettingsService, ApplicationSettingsService>();containerRegistry.RegisterSingleton<IThemeService, ThemeService>();}protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog){// 注册模块moduleCatalog.AddModule<CustomersModule>();moduleCatalog.AddModule<OrdersModule>();moduleCatalog.AddModule<ProductsModule>();}
}
6.2 Shell视图
<Window x:Class="MyPrismApp.Views.Shell"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:prism="http://prismlibrary.com/"Title="Prism应用示例" Height="600" Width="800"><Grid><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><!-- 顶部菜单 --><Menu Grid.Row="0"><MenuItem Header="文件"><MenuItem Header="退出" Command="{Binding ExitCommand}"/></MenuItem><MenuItem Header="客户" Command="{Binding NavigateCommand}" CommandParameter="Customers"/><MenuItem Header="订单" Command="{Binding NavigateCommand}" CommandParameter="Orders"/><MenuItem Header="产品" Command="{Binding NavigateCommand}" CommandParameter="Products"/></Menu><!-- 主内容区域 --><ContentControl Grid.Row="1" prism:RegionManager.RegionName="MainRegion" /><!-- 状态栏 --><StatusBar Grid.Row="2"><TextBlock Text="{Binding StatusMessage}" /></StatusBar></Grid>
</Window>
7. 最佳实践
7.1 模块设计原则
- 每个模块应该是自包含的,拥有自己的视图、视图模型和服务
- 模块之间通过接口和事件聚合器通信,避免直接引用
- 共享功能应放在核心模块中
7.2 性能优化
- 使用按需加载模块,减少启动时间
- 合理使用CompositeCommand,避免过多的命令绑定
- 优化区域管理器的视图切换
// 配置按需加载模块
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{// 启动时加载moduleCatalog.AddModule<CoreModule>();// 按需加载moduleCatalog.AddModule(typeof(ReportsModule).Name, typeof(ReportsModule).AssemblyQualifiedName, InitializationMode.OnDemand);
}
7.3 测试策略
Prism的松散耦合设计使得单元测试变得简单:
[TestMethod]
public void CanExecuteSubmitOrder_WithValidOrder_ReturnsTrue()
{// Arrangevar orderServiceMock = new Mock<IOrderService>();var viewModel = new OrderViewModel(orderServiceMock.Object);var order = new Order { IsValid = true };viewModel.CurrentOrder = order;// Actbool canExecute = viewModel.SubmitOrderCommand.CanExecute();// AssertAssert.IsTrue(canExecute);
}
8. 与其他框架的比较
特性 | Prism | MVVM Light | Caliburn.Micro |
---|---|---|---|
模块化 | ✓ | ✗ | 部分支持 |
依赖注入 | ✓ | 部分支持 | ✓ |
区域管理 | ✓ | ✗ | ✗ |
事件聚合器 | ✓ | ✓ | ✓ |
导航框架 | ✓ | 部分支持 | ✓ |
对话框服务 | ✓ | ✗ | ✓ |
学习曲线 | 中等 | 低 | 高 |
社区支持 | 活跃 | 一般 | 一般 |
9. 总结
Prism框架是构建企业级WPF应用程序的强大工具,它提供了模块化、松散耦合和MVVM支持等关键特性。通过使用Prism,开发人员可以创建可维护、可测试和可扩展的应用程序。
虽然Prism有一定的学习曲线,但其提供的功能和架构优势使其成为大型WPF应用程序开发的理想选择。对于需要构建复杂、模块化桌面应用的团队来说,投资学习Prism将带来长期的收益。
10. 参考资源
- Prism官方文档
- Prism GitHub仓库
- Prism参考应用
- Brian Lagunas的Prism视频教程