Blazor依赖注入报错:未注册指定泛型服务实例
ASP.NET Blazor 泛型服务注入错误修复
场景回顾
项目结构:
- Client:Blazor WebAssembly应用
- BaseLibrary:存储DTO和实体类(Allergies、Medication、Disease、Ingredient)
- ClientLibrary:包含
IGenericServiceInterface<T>泛型接口和GenericServiceImplementation<T>实现类,用于API调用
已完成操作:
- 在Client的Program.cs中注册了针对BaseLibrary实体的泛型服务
- 在_imports.razor中注入了对应服务
核心代码示例
Medication实体类(BaseLibrary)
using BaseLibrary.EntitiesRelation; using Microsoft.EntityFrameworkCore; using System.ComponentModel.DataAnnotations; namespace BaseLibrary.Entities { [Index(nameof(Medication_Name), IsUnique = true)] public class Medication { [Key] public int Medication_Id { get; set; } public string? Medication_Name { get; set; } // Relation N:M public virtual ICollection<Patient_Medication> PatientMedications { get; set; } = new List<Patient_Medication>(); } }
IGenericServiceInterface接口
using BaseLibrary.Responses; namespace ClientLibrary.Services.Contracts { public interface IGenericServiceInterface<T> { Task<List<T>> GetAll(string baseUrl); Task<T> GetById(int id, string baseUrl); Task<GeneralResponse> Insert(T item, string baseUrl); Task<GeneralResponse> Update(T item, string baseUrl); Task<GeneralResponse> Delete(int id, string baseUrl); } }
GenericServiceImplementation实现类
using System.Net.Http.Json; using BaseLibrary.Responses; using ClientLibrary.Helpers; using ClientLibrary.Services.Contracts; namespace ClientLibrary.Services.Implementations { public class GenericServiceImplementation<T>(GetHttpClient getHttpClient) : IGenericServiceInterface<T> { // Create public async Task<GeneralResponse> Insert(T item, string baseUrl) { var httpClient = await getHttpClient.GetPrivateHttpClient(); var response = await httpClient.PostAsJsonAsync($"{baseUrl}/add", item); var result = await response.Content.ReadFromJsonAsync<GeneralResponse>(); return result!; } // Read All public async Task<List<T>> GetAll(string baseUrl) { var httpClient = await getHttpClient.GetPrivateHttpClient(); var result = await httpClient.GetFromJsonAsync<List<T>>($"{baseUrl}/all"); return result!; } // Update public async Task<GeneralResponse> Update(T item, string baseUrl) { var httpClient = await getHttpClient.GetPrivateHttpClient(); var response = await httpClient.PutAsJsonAsync($"{baseUrl}/update", item); var result = await response.Content.ReadFromJsonAsync<GeneralResponse>(); return result!; } // Delete public async Task<GeneralResponse> Delete(int id, string baseUrl) { var httpClient = await getHttpClient.GetPrivateHttpClient(); var response = await httpClient.DeleteAsync($"{baseUrl}/delete/{id}"); var result = await response.Content.ReadFromJsonAsync<GeneralResponse>(); return result!; } public async Task<T> GetById(int id, string baseUrl) { var httpClient = await getHttpClient.GetPrivateHttpClient(); var result = await httpClient.GetFromJsonAsync<T>($"{baseUrl}/single/{id}"); return result!; } } }
Program.cs注册代码
builder.Services.AddScoped<IGenericServiceInterface<Allergies>, GenericServiceImplementation<Allergies>>(); builder.Services.AddScoped<IGenericServiceInterface<Diseases>, GenericServiceImplementation<Diseases>>(); builder.Services.AddScoped<IGenericServiceInterface<Ingredient>, GenericServiceImplementation<Ingredient>>(); builder.Services.AddScoped<IGenericServiceInterface<Medication>, GenericServiceImplementation<Medication>>();
_Imports.razor注入代码
@inject IGenericServiceInterface<Allergies> allergyService @inject IGenericServiceInterface<Diseases> diseaseService @inject IGenericServiceInterface<Ingredient> ingredientService @inject IGenericServiceInterface<Medication> medicationService
错误信息
点击Allergies页面时触发异常:
Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] Unhandled exception rendering component: Cannot provide a value for property 'medicationService' on type 'Client.Pages.ContentPages.AdminFunctions.Allergies'. There is no registered service of type 'ClientLibrary.Services.Contracts.IGenericServiceInterface`1[Client.Pages.ContentPages.AdminFunctions.Medication]'. System.InvalidOperationException: Cannot provide a value for property 'medicationService' on type 'Client.Pages.ContentPages.AdminFunctions.Allergies'. There is no registered service of type 'ClientLibrary.Services.Contracts.IGenericServiceInterface`1[Client.Pages.ContentPages.AdminFunctions.Medication]'. ...(堆栈信息省略)
问题根源
错误信息明确显示:Blazor尝试注入的是**Client.Pages.ContentPages.AdminFunctions.Medication类型的服务,但实际注册的是BaseLibrary.Entities.Medication**(从实体类代码的命名空间可确认)。
常见触发原因:
- Allergies页面中错误导入了
Client.Pages.ContentPages.AdminFunctions命名空间下的同名Medication类 - Allergies页面中
medicationService的泛型参数未显式指定命名空间,导致编译器解析到错误的Medication类
修复步骤
1. 修正页面的命名空间引用
打开Client.Pages.ContentPages.AdminFunctions.Allergies.razor,移除错误的using指令,替换为BaseLibrary实体的命名空间:
@* 移除错误引用 *@ @* @using Client.Pages.ContentPages.AdminFunctions *@ @* 添加正确引用 *@ @using BaseLibrary.Entities
2. 显式指定服务注入的实体类型
在Allergies页面中,显式指定泛型参数的完整命名空间,避免类型歧义:
@* 替换原有注入代码 *@ @inject IGenericServiceInterface<BaseLibrary.Entities.Medication> medicationService
3. 验证Program.cs的注册一致性
确保Program.cs中注册的服务使用的是BaseLibrary中的实体(可显式指定命名空间强化正确性):
builder.Services.AddScoped<IGenericServiceInterface<BaseLibrary.Entities.Medication>, GenericServiceImplementation<BaseLibrary.Entities.Medication>>();
额外建议
- 避免在不同命名空间下创建同名类,减少类型歧义
- 注入泛型服务时,优先使用完整命名空间指定实体类型,避免依赖using指令的隐式解析
内容的提问来源于stack exchange,提问作者Szabó Dominik
相关产品推荐
相关产品推荐

