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 = "測試狀態" }); } } }