Blazor 无法为 'MyComponent' 类型的 属性 'ScopeFactory' 提供值,因为 属性 没有 setter

Blazor Cannot provide a value for property 'ScopeFactory' on type 'MyComponent' because the property has no setter

我正在 .NET 6 中编写 Blazor WASM 应用程序。

从 Visual Studio 2022 年 运行 开始,该应用程序在 Debug 中正常运行,但是当我使用 dotnet publish -c Release --nologo 将其部署为静态站点并访问 bin/Release/net6.0/publish/wwwroot 文件夹 localhost 我收到以下错误:

Unhandled exception rendering component: Cannot provide a value for property 'ScopeFactory' on type 'MySolution.Pages.MyComponent' because the property has no setter.

我的组件如下所示:

public class MyComponent : OwningComponentBase
{
    public IOptions Option { get; set; } = Options.Default;

    protected override async Task OnInitializedAsync()
    {
        Options = await ScopedServices.GetRequiredService<Task<IOptions>>();
    }
}

我在Program.cs中这样添加服务

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped<Task<IOptions>>(async op => await Options.Create(op.GetRequiredService<HttpClient>()));

Options.Create() 看起来像这样

public static async Task<IGameOptions> Create(HttpClient client)
{
    var json = await client.GetStringAsync("/gameOptions.json");

    var options = JsonConvert.DeserializeObject<Options>(json);

    if (options is null)
    {
        throw new InvalidDataException("Given path contains invalid JSON object.");
    }

    return options;
}

我已经做了很多测试和搜索,但我找不到任何东西。我试图在我的组件中只请求 HttpClient 服务,但即使这样也会引发相同的错误。

我发现这是 DI 中的一些问题,但我使用 OwningComponentBase 管理 DI 范围,正如 ASP.NET Core Blazor dependency injection.

中所述

可能是什么原因造成的?

提前致谢

感谢您在评论中发布真实代码。 看了之后,这看起来是 trimming.

的结果

尝试将 <PublishTrimmed>false</PublishTrimmed> 添加到您的项目文件中,我认为它会起作用。

基本上,当您 运行 命令 dotnet publish -c Release --nologo 时,它会优化程序集的大小(修剪)。 在您的情况下,它似乎正在更改 OwningComponentBase 中的以下代码:

[Inject] IServiceScopeFactory ScopeFactory { get; set; }

至:

[Inject] IServiceScopeFactory ScopeFactory { get; }

即它在修剪过程中删除了 setter。

我会认为这是实施中的一个错误

标记的答案只能在您不想 trim 发布您的应用时使用,这并不总是可取的。 如果你想用 trimming 发布你必须从 trimming.

中排除类型
<assembly fullname="Microsoft.AspNetCore.Components">
    <type fullname="Microsoft.AspNetCore.Components.OwningComponentBase" preserve="all" />
</assembly>

因为整个 trimming 本身就是一个主题我可以推荐这个页面来开始调整 trimming 过程:.Net Blog - Customizing Trimming 博客 post 是为 .Net5 编写的,但我也将其用于 .Net6。