我曾经在MVC应用程序中拥有一个通用服务,将其注册为Transient服务,并在整个应用程序中毫无问题地访问其价值。
我尝试在客户端blazor应用程序中实现相同的机制
首先创建一个类AppState
public class AppState
{
public string BaseUrl { get; set; }
}
注册为服务
services.AddSingleton<AppState, AppState>();
用于Blazor组件索引组件
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
@page "/"
@inherits IndexComponent
<p>@AppState.BaseUrl</p>
直到这里很好,因为它包含基本URL,所以我想在另一个组件中访问它
public class MiniCartComponent : ComponentBase
{
[Inject]
public AppState AppState { get; set; }
protected override async Task OnInitializedAsync()
{
await Task.FromResult(0);
}
}
这里是空的,我不知道为什么
我试图将其打印为剃刀文件
@inherits MiniCartComponent
<p>@AppState.BaseUrl</p>
这里为空,它被注册为跨组件共享数据的服务,一旦设置,就不应在整个应用程序中具有价值?
答案 0 :(得分:3)
首先注册一个单例实例
services.AddSingleton<AppState, AppState>();
这对我来说有点奇怪。恕我直言,应该是
services.AddSingleton<IAppState, AppState>();
或
services.AddSingleton<AppState>();
但这不是问题。
您将此服务注入了很棒的组件中
[Inject]
public AppState AppState { get; set; }
然后您通过网络api的新方法擦除了该组件实例
protected override async Task OnInitializedAsync()
{
AppState = await Http.GetJsonAsync<AppState>(ConfigFiles.GetPath("appsettings.json"));
await Task.FromResult(0);
}
他们的代码又很奇怪,应该是
protected override async Task OnInitializedAsync()
{
AppState = await Http.GetJsonAsync<AppState>(ConfigFiles.GetPath("appsettings.json"));
}
但这不会重置您在第二个组件中注入的单例实例。只需替换实例中的第一个组件即可。
services.AddSingleton<AppState>(provider =>
{
var http = provider.GetRequiredService<HttpClient>();
return http.GetJsonAsync<AppState>(ConfigFiles.GetPath("appsettings.json")).ConfigureAwait(false).GetAwaiter().GetResult();
});
通过这种方式,您可以在应用程序生命周期内仅调用一次 appsettings.json 。 (恕我直言,使用 appsettings.json 不是一个好习惯,您应该使用另一个配置文件,例如 clientsettings.json 作为示例)。
OnInitializedAsync
代码。但是实际上,最好的方法是注册Task
以返回设置
services.AddSingleton(provider =>
{
var http = provider.GetRequiredService<HttpClient>();
return http.GetJsonAsync<AppState>("appsettings.json");
});
您可以通过以下方式将其注入您的组件中
[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>