WPF 程序使用 MediatR
1 修改App.xam
让WPF应用启动时不要直接实例化主窗口,而是通过DI获取
删除掉 StartupUri="Views\MainWindow.xaml"
<Application x:Class="YourNamespace.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Views\MainWindow.xaml"> <!-- Remove StartupUri to avoid directly instantiating MainWindow --> </Application>
2 在OnStartup
方法中初始化一个新的ServiceProvider,并配置服务
1 using MediatR; 2 using Microsoft.Extensions.DependencyInjection; 3 using System; 4 using System.ComponentModel; 5 using System.Diagnostics; 6 using System.Text.Json; 7 using System.Threading; 8 using System.Threading.Tasks; 9 using System.Windows; 10 11 namespace MediatRDemo 12 { 13 /// <summary> 14 /// Interaction logic for App.xaml 15 /// </summary> 16 public partial class App : Application 17 { 18 private ServiceProvider? _serviceProvider; 19 protected override async void OnStartup(StartupEventArgs e) 20 { 21 var serviceCollection = new ServiceCollection(); 22 // 添加MediatR及其处理器 23 serviceCollection.AddMediatR(cfg => 24 { 25 cfg.RegisterServicesFromAssembly(typeof(App).Assembly); 26 }); 27 28 // 注册其他服务 29 serviceCollection.AddSingleton<MainWindow>(); 30 31 // 构建ServiceProvider 32 _serviceProvider = serviceCollection.BuildServiceProvider(); 33 34 var mainWindow = _serviceProvider.GetRequiredService<MainWindow>(); 35 36 //var hostBuilder = new HostBuilder().ConfigureServices((hostContext, services) => 37 //{ 38 // services.AddMediatR(typeof(App).Assembly); // 注册MediatR及处理器所在的程序集 39 40 //}); 41 //await hostBuilder.StartAsync(); 42 43 //var mainWindow = hostBuilder.Services.GetService<MainWindow>(); 44 mainWindow.Show(); 45 46 } 47 48 protected override void OnExit(ExitEventArgs e) 49 { 50 // 清理ServiceProvider(如果需要) 51 _serviceProvider?.Dispose(); 52 base.OnExit(e); 53 } 54 } 55 56 57 #region 状态通知 58 59 public class NoticeStatus : INotification 60 { 61 /// <summary> 62 /// 任务号 63 /// </summary> 64 public string? TaskNo { get; set; } 65 /// <summary> 66 /// 状态 67 /// </summary> 68 public object? State { get; set; } 69 /// <summary> 70 /// 备注 71 /// </summary> 72 public string? Remark { get; set; } 73 } 74 75 public class NoticeStandEndHandle : INotificationHandler<NoticeStatus> 76 { 77 //todo 可在构造函数中出入已经注入的实体 78 79 80 public Task Handle(NoticeStatus notification, CancellationToken cancellationToken) 81 { 82 var json = JsonSerializer.Serialize(notification); 83 //todo 状态操作 84 Debugger.Log(1, "测试", json); 85 return Task.CompletedTask; 86 } 87 } 88 89 90 #endregion 91 92 #region 日志 93 94 public class NoticeCellLog : INotification 95 { 96 public string? Address { get; set; } 97 public string? Message { get; set; } 98 public EnumLogLevel LogType { get; set; } 99 } 100 101 public class NoticeCellLogHandler : INotificationHandler<NoticeCellLog> 102 { 103 /* 104 /// <summary> 105 /// 可以在构造函数传入多个注入的实体 106 /// </summary> 107 public NoticeCellLogHandler( 108 UILogShow uiLogShow, 109 ILogNetRecord logNetRecord) 110 { 111 _uiLogShow = uiLogShow; 112 _logNetRecord = logNetRecord; 113 } 114 */ 115 116 public Task Handle(NoticeCellLog notification, CancellationToken cancellationToken) 117 { 118 var json = JsonSerializer.Serialize(notification); 119 Debugger.Log(1, "测试", json); 120 //todo 日志操作 121 // 记录日志操作 122 return Task.CompletedTask; 123 } 124 } 125 126 public enum EnumLogLevel 127 { 128 /// <summary> 129 /// 错误 130 /// </summary> 131 [Description("错误")] 132 Error = 0, 133 /// <summary> 134 /// 警告 135 /// </summary> 136 [Description("警告")] 137 Warning = 1, 138 /// <summary> 139 /// 信息 140 /// </summary> 141 [Description("提示")] 142 Info = 2, 143 /// <summary> 144 /// 调试 145 /// </summary> 146 [Description("调试")] 147 Debug = 3, 148 } 149 150 #endregion 151 }
3 在MainWindow.xaml.cs 发布通知
using MediatR; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace MediatRDemo { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private readonly IMediator _mediator; public MainWindow(IMediator mediator) { InitializeComponent(); _mediator = mediator; } private async void Button_Click(object sender, RoutedEventArgs e) { await _mediator.Publish(new NoticeStatus() { TaskNo = Guid.NewGuid().ToString(), State = TaskStatus.Running, Remark = "测试状态" }); } private async void Button_Click_1(object sender, RoutedEventArgs e) { await _mediator.Publish(new NoticeCellLog() { Address = Guid.NewGuid().ToString(), LogType = EnumLogLevel.Info, Message = "测试状态" }); } } }