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。
我正在 .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。