WPF 程式使用 MediatR

永恒921發表於2024-06-29

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

相關文章