简体   繁体   English

Blazor 的依赖注入问题

[英]Dependency Injection issues with Blazor

I am using .NET 5 and Blazor and also I am using DevExpress to create Pie Chart.我正在使用 .NET 5 和 Blazor 并且我正在使用 DevExpress 创建饼图。

The problem I have is, that inside of the main page, I have a few blazor components, and every component has a DevExpress pie chart.我遇到的问题是,在主页里面,我有几个 blazor 组件,每个组件都有一个 DevExpress 饼图。

What I need is to inject a class inside of every component, and I need to every component to manage his own instance of this object, but it looks like I have one object per URL, how can I solve this?我需要的是在每个组件中注入一个 class,我需要每个组件管理他自己的这个 object 实例,但看起来我每个 URL 都有一个 object,我该如何解决这个问题?

This is the code of one of the components with one DevExpress donut chart:这是带有一个 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;
    }
}

This is the object I am trying to inject:这是我要注入的 object:

@inject IColorPaletteService _colorPaletteService

And this is the code of the class I am trying to inject:这是我要注入的 class 的代码:

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];
            }
        }
    }
}

The problem I have is that having scoped injected this object, but the scope is not every component but looks like is one object by URL, this cause that the function "GetNextColor" of the class "ColorPaletteService" pass a kind of random colors instead of following the order of the variable "ColorList". The problem I have is that having scoped injected this object, but the scope is not every component but looks like is one object by URL, this cause that the function "GetNextColor" of the class "ColorPaletteService" pass a kind of random colors instead of按照变量“ColorList”的顺序。

Any help please?有什么帮助吗?

The class should be added as Transient: class 应添加为 Transient:

services.AddTansient<IColorPaletteService, ColorPaletteService>();

this will give each component its own instance.这将为每个组件提供自己的实例。

You are trying to maintain a component-specific state inside an injected service instance.您正在尝试在注入的服务实例中维护特定于组件的 state。 Instead, you should maintain the state inside the component.相反,您应该在组件内部维护 state。 Your code can then look like this:您的代码可能如下所示:

PieChart.razor饼图.razor

@code
{
   int currentColorIndex = 0;
   protected void PreparePointColor(ChartSeriesPointCustomizationSettings pointSettings)
    {
        currentColorIndex = colorPaletteService.GetNextColor(currentColorIndex, out var color);
        pointSettings.PointAppearance.Color = color;
    }
}

And palette service as:调色板服务为:

public int GetNextColor(int CurrentColorIndex, out Color col)
{
      col = CurrentColorIndex < ListLenght ? ColorList[CurrentColorIndex] : ColorList[0];
      return CurrentColorIndex >= ListLenght ? 0 : CurrentColorIndex+1;    
}

And set the palette service as a singleton. Note that the transients in the blazor server are poorly defined.并将调色板服务设置为 singleton。请注意,blazor 服务器中的瞬态定义不明确。 Server WebSocket keeps the session alive as long as it is not disconnected.服务器 WebSocket 保持 session 活动,只要它没有断开连接。 So the transients here behave differently than in the traditional .net controller.所以这里的瞬态行为不同于传统的 .net controller。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM