中的服务共享数据

中的服务共享数据

本文介绍了通过 ASP.NET Blazor 中的服务共享数据(客户端)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾经在 MVC 应用程序中有一个公共服务,将其注册为瞬态服务并在整个应用程序中访问其值而没有任何问题.

I use to have a common service in MVC Application , register it as Transient service and access its value across whole application without any issue .

我尝试在我的客户端 blazor 应用程序中实现相同的机制

I tried to implement same mechanism inside my client side blazor app

首先创建了一个类 AppState

First created a class AppState

public class AppState
{
    public string BaseUrl { get; set; }
}

注册为服务

services.AddSingleton<AppState, AppState>();

在 Blazor 组件索引组件中使用

Used in Blazor Component Index Component

public class IndexComponent : ComponentBase
{
    [Inject]
    HttpClient Http { get; set; }

    [Inject]
    public AppState AppState { get; set; }

    protected override async Task OnInitializedAsync()
    {
        AppState = await Http.GetJsonAsync<AppState>(ConfigFiles.GetPath("appsettings.json"));
        await Task.FromResult(0);
    }
}

尝试在 index.razor 文件中打印基本 url

Tried to print base url in index.razor file

@page "/"
@inherits IndexComponent

<p>@AppState.BaseUrl</p>

直到这里很好,现在因为它包含基本网址,所以我想在另一个组件中访问它

Till Here its fine , now as it contain base url so i wanted to access it in another component

public class MiniCartComponent : ComponentBase
{
    [Inject]
    public AppState AppState { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await Task.FromResult(0);
    }
}

这里是空的,我不知道为什么

Here it is empty , i dont know why

我试图在剃刀文件中打印它

I tried to print it in razor file

@inherits MiniCartComponent
<p>@AppState.BaseUrl</p>

这里是空的,它被注册为一个跨组件共享数据的服务,一旦设置,它不应该在整个应用程序中有价值吗??

Here it is empty , it is registered as a service to share data across components , should not it have value across the app once it is set ??

推荐答案

第一次注册一个单例实例

1st you register a singleton instance

services.AddSingleton<AppState, AppState>();

这对我来说有点奇怪.恕我直言,应该是

this look a bit weird to me. IMHO, it should be

services.AddSingleton<IAppState, AppState>();

services.AddSingleton<AppState>();

但这不是问题所在.

您将此服务注入到一个很棒的组件中

You inject this service in a component whicht is great

[Inject]
public AppState AppState { get; set; }

然后你用一个新的从 web api 获取的组件实例擦除这个组件

And you erase this component instance with a new one get from a web api

protected override async Task OnInitializedAsync()
{
    AppState = await Http.GetJsonAsync<AppState>(ConfigFiles.GetPath("appsettings.json"));
    await Task.FromResult(0);
}

他们的代码又很奇怪,应该是

Their again the code is weird, it should be

protected override async Task OnInitializedAsync()
{
    AppState = await Http.GetJsonAsync<AppState>(ConfigFiles.GetPath("appsettings.json"));
}

但这不会重置您在第二个组件中注入的单例实例.那只是替换第一个组件中的实例.

But that doesn't reset the singleton instance you inject in your second component. That just replace the instance in your 1st component.

  • 您应该使用
  • 注册您的服务
services.AddSingleton<AppState>(provider =>
{
    var http = provider.GetRequiredService<HttpClient>();
    return http.GetJsonAsync<AppState>(ConfigFiles.GetPath("appsettings.json")).ConfigureAwait(false).GetAwaiter().GetResult();
});

通过这种方式,您在应用程序生命周期内只需调用一次 appsettings.json.

This way you make just one call to appsettings.json during the app life.

  • 并删除 OnInitializedAsync 代码.

但实际上,实现这一目标的最佳方法是注册一个 Task 返回您的设置

But actually, the best way to achieve that is to register a Task returning your settings

services.AddSingleton(provider =>
{
    var http = provider.GetRequiredService<HttpClient>();
    return http.GetJsonAsync<AppState>("appsettings.json");
});

您可以将其注入到您的组件中

You can inject it in your components with

[Inject]
public Task<AppState> AppStateAsync { get; set; }

public AppState AppState { get; set; }

protected override async Task OnInitializedAsync()
{
    AppState = await AppStateAsync;
}

并与

@page "/"
@inherits IndexComponent

<p>@AppState.BaseUrl</p>

这篇关于通过 ASP.NET Blazor 中的服务共享数据(客户端)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 05:26