Blazor新手求助:如何实例化C#服务并在组件中使用其数据
解决Blazor共享Todo数据服务的问题
第一步:优化你的Todo服务
原服务存在资源浪费、异步阻塞、类型不安全的问题,优化后的代码如下:
using TodoApp.Models.TodoTestModel; using Newtonsoft.Json; using System.Net.Http; namespace Todo.Services { public class TodoService { private readonly HttpClient _httpClient; public string TodoURL { get; set; } public TodoTestModel? Result { get; private set; } // 注入Blazor默认注册的HttpClient,避免重复创建浪费资源 public TodoService(HttpClient httpClient) { _httpClient = httpClient; // 可在此设置默认URL,也可后续在组件中修改 TodoURL = "http://localhost/todo"; } public async Task<TodoTestModel> GetTodoDataAsync() { // 用await替代.Result,避免异步阻塞 var response = await _httpClient.GetAsync(TodoURL); response.EnsureSuccessStatusCode(); var responseData = await response.Content.ReadAsStringAsync(); Result = JsonConvert.DeserializeObject<TodoTestModel>(responseData); return Result; } } }
第二步:注册服务到依赖注入容器
在Program.cs中添加服务注册,让Blazor能通过@inject为组件提供服务实例:
// 若需全局共享同一数据实例,用AddSingleton;若需按用户会话隔离,用AddScoped builder.Services.AddScoped<TodoService>();
第三步:组件中正确调用服务并传递数据
你之前同时混用@inject和new Todo(),且属性赋值语法错误,正确的组件代码如下:
@page "/" @using Todo.Services @inject TodoService TodoService <h5>List of todos</h5> <!-- 数据加载完成后传递给子组件 --> @if (_todoData != null) { <TodoComponent ToDoResult="@_todoData"></TodoComponent> } else { <p>加载中...</p> } @code { private TodoTestModel? _todoData; protected override async Task OnInitializedAsync() { // 如需修改目标URL,在此设置 TodoService.TodoURL = "http://localhost/todo"; // 调用服务获取数据 _todoData = await TodoService.GetTodoDataAsync(); } }
进阶:实现数据自动共享
如果希望多个组件无需重复请求接口,直接复用已获取的数据,可在服务中添加缓存逻辑:
public async Task<TodoTestModel> GetTodoDataAsync() { // 若已有缓存数据,直接返回,避免重复请求 if (Result != null) return Result; var response = await _httpClient.GetAsync(TodoURL); response.EnsureSuccessStatusCode(); var responseData = await response.Content.ReadAsStringAsync(); Result = JsonConvert.DeserializeObject<TodoTestModel>(responseData); return Result; }
内容的提问来源于stack exchange,提问作者elektra
相关产品推荐
相关产品推荐

