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

.NET MAUI Blazor动态加载程序集时服务注册缺失报错

.NET MAUI Blazor动态加载Shared DLL时依赖注入失败的解决办法

问题场景

项目包含MAUI、Shared、Web三个工程,UI代码全部在Shared中,MAUI和Web工程实现Shared中的接口。需实现应用启动时检查服务器新版本,下载更新后的Shared DLL并动态加载。当前已编写动态加载逻辑,但运行时抛出错误:

'Cannot provide a value for property 'FormFactor' on type 'MyProject.Shared.Components.Pages.DeviceFormFactor'. There is no registered service of type 'MyProject.Shared.Interfaces.IFormFactor''

错误原因

动态加载的更新版Shared DLL被加载到独立的AssemblyLoadContext中,该上下文内的IFormFactor接口类型,与MAUI项目启动时注册到DI容器中的IFormFactor接口(来自主应用的AssemblyLoadContext)不属于同一类型系统。DI容器无法识别跨上下文的同名接口,因此找不到对应服务实现。

解决方案

1. 拆分接口到独立类库(推荐)

将MyProject.Shared.Interfaces中的所有接口提取到单独的类库项目(如MyProject.Core.Interfaces),让MAUI、Shared、Web三个项目都引用该类库。这样主应用和动态加载的Shared DLL会使用同一个程序集内的接口类型,从根源避免类型不匹配问题。

2. 配置动态加载上下文共享主依赖

若不拆分接口,修改动态加载逻辑,让自定义AssemblyLoadContext优先从主应用上下文获取已加载的依赖程序集(尤其是接口所在的Shared程序集):

修改LoadDynamicAssembly方法:

private void LoadDynamicAssembly()
{
    try
    {
        var dllPath = Components.Layout.DownloadLayout.GetFrontendFilePath();
        // 创建共享主上下文依赖的AssemblyLoadContext
        var assemblyLoadContext = new AssemblyLoadContext("DynamicAssemblyContext", isCollectible: true)
        {
            Resolving = (alc, name) =>
            {
                // 优先从主应用上下文加载依赖程序集
                var mainAssembly = AssemblyLoadContext.Default.LoadFromAssemblyName(name);
                return mainAssembly ?? alc.LoadFromAssemblyName(name);
            }
        };
        
        var assembly = assemblyLoadContext.LoadFromAssemblyPath(dllPath);
        var componentType = assembly.GetType("MyProject.Shared.Components.Routes");
        if (componentType == null)
        {
            throw new Exception("未在程序集中找到类型 MyProject.Shared.Components.Routes。");
        }

        Logger.LogInformation("找到组件。正在更新UI。");

        // 清理并加载新组件
        ReinitializeBlazorWebView(componentType);
    }
    catch (Exception ex)
    {
        Logger.LogError(ex, "加载程序集或组件时出错。");
        DisplayAlert("错误", $"加载组件失败: {ex.Message}", "确定");
    }
}

3. 验证服务注册一致性

确认MAUI项目中IFormFactor的注册逻辑正确,确保实现类已被注入:

// MauiProgram.cs中已正确注册,无需修改
builder.Services.AddSingleton<IFormFactor, FormFactor>();

关键说明

动态加载程序集时,类型标识由程序集+类型全名+AssemblyLoadContext共同决定,即使类型名称完全相同,来自不同上下文的类型也会被视为不同类型。通过共享接口程序集或让自定义上下文复用主上下文的依赖,可解决这种类型不匹配导致的DI注入失败问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 21:53:12