You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF中App.xaml.cs依赖注入时的异常处理方案咨询

解决方案

一、在应用启动入口捕获异常并弹出提示

WPF启动阶段的DI初始化异常会直接终止进程,你可以在App.xaml.cs的OnStartup方法(或.NET 6+的Program.cs主入口)中包裹服务提供者的构建逻辑,统一捕获异常后弹出提示框:

示例代码(App.xaml.cs)

protected override void OnStartup(StartupEventArgs e)
{
    try
    {
        var services = new ServiceCollection();
        // 注册其他依赖服务
        services.AddSingleton<IConfiguracionServicio, ConfiguracionServicioImpl>();
        // 注册CanalGrpc
        services.AddSingleton<CanalGrpc>(miServiceProvider =>
        {
            string miStrDireccionServidor = GetDireccionServidor(miServiceProvider.GetRequiredService<IConfiguracionServicio>());
            int miIntPuertoServidor = 1;

            if (string.IsNullOrEmpty(miStrDireccionServidor))
            {
                throw new InvalidOperationException("No se ha podido conectar con el servidor.");
            }

            return new CanalGrpc(miStrDireccionServidor, miIntPuertoServidor);
        });

        var serviceProvider = services.BuildServiceProvider();
        // 若启动时需要解析服务,也包裹在此try块内
        var canalGrpc = serviceProvider.GetRequiredService<CanalGrpc>();
    }
    catch (InvalidOperationException ex)
    {
        MessageBox.Show(ex.Message, "Error de Conexión", MessageBoxButton.OK, MessageBoxImage.Error);
        Shutdown(); // 关闭应用
        return;
    }

    base.OnStartup(e);
}

注:原GetDireccionServidor返回空字符串的场景也要处理,避免后续创建CanalGrpc实例时出现隐性错误。

二、延迟初始化服务,避免启动时阻塞

如果不需要在启动阶段就检测连接,可以将CanalGrpc注册为延迟初始化实例,仅在第一次使用时尝试创建,此时可在业务逻辑中捕获异常:

修改注册逻辑

services.AddSingleton<Lazy<CanalGrpc>>(miServiceProvider =>
{
    return new Lazy<CanalGrpc>(() =>
    {
        string miStrDireccionServidor = GetDireccionServidor(miServiceProvider.GetRequiredService<IConfiguracionServicio>());
        int miIntPuertoServidor = 1;

        if (string.IsNullOrEmpty(miStrDireccionServidor))
        {
            throw new InvalidOperationException("No se ha podido conectar con el servidor.");
        }

        return new CanalGrpc(miStrDireccionServidor, miIntPuertoServidor);
    });
});

使用时捕获异常

在ViewModel或业务代码中调用时处理:

public class MainViewModel
{
    private readonly Lazy<CanalGrpc> _canalGrpcLazy;

    public MainViewModel(Lazy<CanalGrpc> canalGrpcLazy)
    {
        _canalGrpcLazy = canalGrpcLazy;
    }

    public void ConectarServidor()
    {
        try
        {
            var canalGrpc = _canalGrpcLazy.Value;
            // 执行后续业务逻辑
        }
        catch (InvalidOperationException ex)
        {
            MessageBox.Show(ex.Message, "Error de Conexión", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }
}

三、调整地址检测逻辑,提前处理异常

修改GetDireccionServidor方法,不直接抛出异常,而是返回可空字符串,再在服务注册或启动阶段判断结果:

修改后的地址检测方法

private string? GetDireccionServidor(IConfiguracionServicio configuracion)
{
    try
    {
        Ping miPing = new Ping();
        PingOptions misOpcionesPing = new PingOptions { DontFragment = true };

        var direcciones = new List<string> { "1.1.1.1", "2.2.2.2", "3.3.3.3" };
        foreach (var dir in direcciones)
        {
            PingReply miRespuestoPing = miPing.Send(dir, 500);
            if (miRespuestoPing.Status == IPStatus.Success)
            {
                return dir;
            }
        }

        return null;
    }
    catch (Exception ex)
    {
        // 可在此处添加日志记录
        return null;
    }
}

注册时的结果判断

services.AddSingleton<CanalGrpc>(miServiceProvider =>
{
    var configuracion = miServiceProvider.GetRequiredService<IConfiguracionServicio>();
    string? miStrDireccionServidor = GetDireccionServidor(configuracion);
    
    if (miStrDireccionServidor == null)
    {
        throw new InvalidOperationException("No se ha podido conectar con el servidor.");
    }

    int miIntPuertoServidor = 1;
    return new CanalGrpc(miStrDireccionServidor, miIntPuertoServidor);
});

此方式可将异常统一抛到启动入口处理,也可结合延迟初始化灵活调整。


内容的提问来源于stack exchange,提问作者Álvaro García

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:00:10