Blazor Web App双Program.cs依赖注入配置及代码复用疑问
Blazor Web App 依赖注入配置方案
核心结论
需要分别在服务器端和客户端的Program.cs中配置依赖容器,但可以通过提取共享配置的方式消除代码重复——这是由Blazor Web App的双运行环境特性决定的。
为什么两端都要配置?
Blazor Web App的服务器端(Server)和客户端(Interactive WebAssembly模式下)是完全独立的运行环境:
- 服务器端服务运行在ASP.NET Core后端进程中,可直接访问数据库、文件系统等后端资源;
- 客户端服务运行在浏览器的WASM沙箱内,只能访问浏览器API或通过HTTP调用后端接口。
你之前只在一端注册出现「未注册服务」错误,本质是服务的运行环境不匹配:比如客户端需要的HTTP客户端没在客户端容器注册,或者服务器端需要的数据库上下文没在服务器端容器注册,导致服务找不到。
Clean Architecture下的优化方案
利用Clean Architecture的分层特性,把共享服务的配置提取到类库项目中,两端各自引用并调用共享配置,再补充环境特有服务即可:
1. 提取共享配置
在你的Infrastructure层(或单独新建一个DependencyInjection类库)创建静态扩展方法,统一注册跨环境的共享服务:
public static class DependencyInjection { public static IServiceCollection AddSharedServices(this IServiceCollection services) { // 注册领域服务、映射配置等共享服务 services.AddScoped<IMyDomainService, MyDomainService>(); services.AddAutoMapper(typeof(MappingProfile)); return services; } }
2. 服务器端Program.cs配置
先调用共享配置,再添加服务器端专属服务(数据库、API控制器、服务器端Blazor服务等):
var builder = WebApplication.CreateBuilder(args); // 加载共享服务配置 builder.Services.AddSharedServices(); // 服务器端特有配置 builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddControllers(); builder.Services.AddServerSideBlazor(); var app = builder.Build(); // ...后续中间件配置
3. 客户端Program.cs配置(Interactive WebAssembly模式)
同样先调用共享配置,再添加客户端专属服务(HTTP客户端、前端状态管理、JS互操作服务等):
var builder = WebAssemblyHostBuilder.CreateDefault(args); // 加载共享服务配置 builder.Services.AddSharedServices(); // 客户端特有配置 builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddScoped<IClientStateService, ClientStateService>(); await builder.Build().RunAsync();
关键注意事项
- 区分服务运行环境:绝对不能将服务器端专属服务(如
DbContext)注册到客户端,反之亦然,否则会引发运行时错误; - 确认交互模式:如果你的Blazor Web App使用的是Interactive Server模式,客户端没有独立的WASM运行时,所有组件都在服务器端运行,此时客户端
Program.cs几乎不需要配置服务,大部分依赖都可以在服务器端注册。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

