WPF 中引入依赖注入(.NET 通用主机)

WPF 中引入依赖注入(.NET 通用主机)

在网上看到的文章都是通过 App.cs 中修改配置进行的,这样侵入性很高而且服务主机是通过 App 启动时加载的而不是服务主机加载的 App 有一点违反原则。目前,借助 C# 9.0 带来的顶层语句可以轻松解决这个问题。

方案

  1. 在 nuget 中安装 Microsoft.Extensions.Hosting
  2. 在根目录新建 Program.cs,改为下面的代码
using TestProgram;
using TestProgram.Common;
// 使用 .NET 依赖注入库
using Microsoft.Extensions.DependencyInjection;
// 使用 .NET 通用主机
using Microsoft.Extensions.Hosting;
using System.Threading;

// 窗口化应用需要在 STA 模式下运行,设置当前
if (!Thread.CurrentThread.TrySetApartmentState(ApartmentState.STA))
{
    Thread.CurrentThread.SetApartmentState(ApartmentState.Unknown);
    Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
}
// 构建默认主机
var builder = Host.CreateDefaultBuilder();
// 配置
await builder.ConfigureServices(services =>
{
    services.AddLogging();
    // 注入 ViewModel(自行实现非官方)
    services.AddViewModels();
    // 注入 View(自行实现非官方)
    services.AddViews();
    // 注入 WPF 启动类 App
    services.AddSingleton<App>();
    // 启动 WPF 服务
    services.AddHostedService<WPFRunner<App, MainWindow>>();
}).Build().RunAsync();
  1. 编写 WPFRunner 用于启动 WPF 服务,在适合的命名空间中新建一个 WPFRunner.cs 文件,插入下面的代码
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TestProgram.Common
{
    public class WPFRunner<TApplication, TWindow> : IHostedService where TApplication : System.Windows.Application where TWindow : System.Windows.Window
    {
        private readonly TApplication application;
        private readonly TWindow window;
        public WPFRunner(TWindow window, TApplication application)
        {
            this.window = window;
            this.application = application;
        }
        // 参考 ASP.NET 中的后台服务(见下方参考)
        public Task StartAsync(CancellationToken cancellationToken)
        {
            // 启动
            application.Run(window);
            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            // 结束
            application.Shutdown();
            return Task.CompletedTask;
        }
    }
}

参考

  1. .NET 通用主机
  2. 顶级语句 - 不使用 Main 方法的程序
  3. IHostedService 接口
posted @ 2022-04-25 10:48  Aoba_xu  阅读(1211)  评论(4编辑  收藏  举报