Blazor 的依赖注入问题
Posted
技术标签:
【中文标题】Blazor 的依赖注入问题【英文标题】:Dependency Injection issues with Blazor 【发布时间】:2021-09-26 17:55:08 【问题描述】:我正在使用 .NET 5 和 Blazor,并且我正在使用 DevExpress 创建饼图。
我的问题是,在主页面内部,我有几个 blazor 组件,每个组件都有一个 DevExpress 饼图。
我需要在每个组件内部注入一个类,并且我需要每个组件管理他自己的这个对象的实例,但是看起来我每个 URL 都有一个对象,我该如何解决这个问题?
这是带有一个 DevExpress 圆环图的组件之一的代码:
@using System.Drawing;
@inject IColorPaletteService _colorPaletteService
<hr class="border-gold" />
<h4 class="text-center text-active">Overall</h4>
<DxChart Data="@_genderList" CustomizeSeriesPoint="@PreparePointColor"
CssClass="w-100">
<DxChartLegend Visible="false" />
<DxChartDonutSeries ValueField="@((DashboardValues i) => i.Value)"
ArgumentField="@(i => i.Detail)"
SummaryMethod="Enumerable.Sum">
</DxChartDonutSeries>
</DxChart>
<div style="position: relative; top: -26%; left: 90%; transform: translate(-50%, -50%);">
<h1 class="text-secondary">@Completed%</h1>
</div>
@code
private IEnumerable<DashboardValues> _genderList;
private int Completed get; set;
protected override void OnInitialized()
base.OnInitialized();
_genderList = new List<DashboardValues>
new DashboardValues Id = 1, Detail = "Completed", Value = 90,
new DashboardValues Id = 1, Detail = "Remaining", Value = 10,
;
Completed = _genderList.First(x => x.Detail == "Completed").Value;
protected void PreparePointColor(ChartSeriesPointCustomizationSettings pointSettings)
pointSettings.PointAppearance.Color = _colorPaletteService.GetNextColor;
这是我要注入的对象:
@inject IColorPaletteService _colorPaletteService
这是我要注入的类的代码:
using System.Collections.Generic;
using System.Drawing;
namespace WebClient.Services.Dashboard
public class ColorPaletteService: IColorPaletteService
private List<Color> ColorList get; set;
private int CurrentColorIndex get; set;
private int ListLenght get; set;
public ColorPaletteService()
CurrentColorIndex = 0;
ColorList = new List<Color>
ColorTranslator.Fromhtml("#00546C"),
ColorTranslator.FromHtml("#518197"),
ColorTranslator.FromHtml("#96898A"),
ColorTranslator.FromHtml("#C0AFA5"),
ColorTranslator.FromHtml("#D2C7C3"),
ColorTranslator.FromHtml("#EDE6E0"),
ColorTranslator.FromHtml("#BA9764"),
ColorTranslator.FromHtml("#808080"),
ColorTranslator.FromHtml("#D0D0D0")
;
ListLenght = ColorList.Count;
public Color GetNextColor
get
if (CurrentColorIndex < ListLenght)
Color currentColor = ColorList[CurrentColorIndex];
// Increase the index for the next iteration
CurrentColorIndex += 1;
return currentColor;
CurrentColorIndex = 0;
return ColorList[0];
我遇到的问题是,有范围注入了这个对象,但范围不是每个组件,而是看起来像是一个 URL 对象,这导致类“ColorPaletteService”的函数“GetNextColor”传递了一种随机颜色而不是遵循变量“ColorList”的顺序。
有什么帮助吗?
【问题讨论】:
您遗漏了注册码。我想应该是AddTransient()
。
Inject class by transient not scoped.... Scoped 是每个请求一个... 每次注入类时都会创建一个 ....
@MarcosF8 - 旁注,但 Ssystem.Drawing
在 asp.net 中非常可疑。尽量避免Color
。
【参考方案1】:
您正试图在注入的服务实例中维护特定于组件的状态。相反,您应该维护组件内部的状态。 您的代码可能如下所示:
PieChart.razor
@code
int currentColorIndex = 0;
protected void PreparePointColor(ChartSeriesPointCustomizationSettings pointSettings)
currentColorIndex = colorPaletteService.GetNextColor(currentColorIndex, out var color);
pointSettings.PointAppearance.Color = color;
调色板服务为:
public int GetNextColor(int CurrentColorIndex, out Color col)
col = CurrentColorIndex < ListLenght ? ColorList[CurrentColorIndex] : ColorList[0];
return CurrentColorIndex >= ListLenght ? 0 : CurrentColorIndex+1;
并将调色板服务设置为单例。 请注意,blazor 服务器中的瞬态定义不明确。只要会话未断开连接,服务器 WebSocket 就会使会话保持活动状态。所以这里的瞬态行为与传统的 .net 控制器不同。
【讨论】:
“注入服务中的组件特定状态” - 如何避免在 StateService 中出现这种情况? Transient 在任何地方都是一样的:每个请求 1 个实例。 否(即请求什么?这不是 API 请求)。在 Blazor 服务器中,每次创建组件时都会注入瞬态。此外,组件“创建”可能有点棘手。例如,您提出了一个异步请求并决定在等待时显示一个进度条。那样的话,组件可能会被破坏,所以你要重新开始。看一下这个。 docs.microsoft.com/en-us/aspnet/core/blazor/fundamentals/… 每个解析请求 1 个。 谁做的?什么时候? 感谢您解决了我的问题,即使 Tansient 运行良好,在这种情况下,拥有一个单例对象似乎可以更好地利用资源。感谢您的帮助!【参考方案2】:该类应添加为 Transient:
services.AddTansient<IColorPaletteService, ColorPaletteService>();
这将为每个组件提供自己的实例。
【讨论】:
我尝试了 AddTansient,这次运行良好,没有出现错误。谢谢以上是关于Blazor 的依赖注入问题的主要内容,如果未能解决你的问题,请参考以下文章
Blazor University (48)依赖注入 —— Scoped 依赖