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

.NET5.0 PRISM WPF配置Serilog为Microsoft.Extensions.Logging提供方的注入问题

问题根因

你遇到的No public constructor is available for type System.IServiceProvider错误,核心原因有两个:

  1. Prism.Container.Extensions的RegisterServices方法仅收集IServiceCollection的服务描述,没有自动将服务同步到Unity容器,也没有关联IServiceProvider实现
  2. Microsoft.Extensions.Logging的ILogger<TCategory>解析逻辑依赖IServiceProvider服务,而Unity容器默认没有将自身注册为IServiceProvider的实例,导致解析时Unity尝试构造IServiceProvider实例失败
解决方案

第一步:确认依赖包正确安装

需要的NuGet包列表:

  • Prism.Unity 8.1.97
  • Prism.Container.Extensions.Unity 匹配Prism版本
  • Serilog.Extensions.Logging
  • 你用到的Serilog对应Sink包(如Serilog.Sinks.File、Serilog.Sinks.Console等)
  • Microsoft.Extensions.Configuration.Json

第二步:修改App.xaml.cs代码

调整CreateContainerExtension逻辑

将原来的CreateContainerExtension方法替换为以下实现,完成服务填充和IServiceProvider注册:

protected override IContainerExtension CreateContainerExtension()
{
    // 加载配置文件
    configRoot = new ConfigurationBuilder()
                .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")}.json", optional: false)
                .Build();

    // 提前初始化Serilog,避免日志遗漏
    Log.Logger = new LoggerConfiguration()
        .ReadFrom.Configuration(configRoot)
        .CreateLogger();

    // 手动创建Unity容器实例
    var unityContainer = new UnityContainer();

    // 构建IServiceCollection注册服务
    var services = new ServiceCollection();
    // 注册配置实例供全局使用
    services.AddSingleton<IConfiguration>(configRoot);
    // 注册日志并指定Serilog为提供方
    services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true));

    // 关键:将IServiceCollection中注册的服务填充到Unity容器
    unityContainer.Populate(services);
    // 关键:注册IServiceProvider实例指向当前Unity容器(Unity本身已实现IServiceProvider接口)
    unityContainer.RegisterInstance<IServiceProvider>(unityContainer);

    // 返回Prism要求的容器扩展实例
    return unityContainer.CreateContainerExtension();
}

清理CreateShell中冗余代码

删掉CreateShell里的Serilog初始化逻辑,修改后如下:

protected override Window CreateShell()
{
    return Container.Resolve<MainWindow>();
}
常见疑问解答

Prism.Container.Extensions确实支持像.NET内置DI一样使用IServiceCollection注册服务,只是针对Unity容器需要手动执行Populate方法完成服务同步,以及手动注册IServiceProvider实例,这两个步骤是Unity容器适配Microsoft.Extensions.DependencyInjection的必要操作,你的原有代码漏掉了这两步所以报错。

内容的提问来源于stack exchange,提问作者Angelo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 10:54:04