Blazor Server项目:直接访问数据库还是调用自研ASP.NET Core WebAPI?
先明确两个方案的核心问题
直接访问数据库的隐患
- 重复配置维护成本高:如果在Blazor Server里复制WebAPI的DbContext、DI服务配置,后续Infrastructure类库更新(比如新增仓储实现、修改DbContext配置),你需要同时修改两个项目的Program.cs,极易出现配置不一致的问题,长期维护会非常头疼。
- 打破分层架构边界:你的Core+Infrastructure本来是业务逻辑的核心封装,WebAPI作为对外的网关层负责权限校验、请求限流、响应封装等通用逻辑。Blazor直接连DB等于跳过了这些网关能力,后续如果要加移动端、小程序等客户端,你需要在Blazor里重复实现这些逻辑,完全违背了架构复用的初衷。
- 安全风险提升:Blazor Server服务器需要直接持有数据库连接字符串,增加了数据库的暴露面;同时所有业务逻辑的权限校验要在Blazor里重新实现,容易出现权限漏洞。
调用WebAPI的性能顾虑其实被放大了
Blazor Server是服务器端运行的,你可以配置HttpClient直接调用本地部署的WebAPI(比如http://localhost:5000),这种内部请求的性能损耗极低——没有公网延迟,只是本地进程间的HTTP通信,几乎可以忽略。如果还是担心,还可以做以下优化:
- 用
IHttpClientFactory复用HttpClient实例,避免频繁创建销毁的开销。 - 启用HTTP/2协议,提升请求响应效率。
- 对请求响应启用Gzip压缩,减少数据传输量。
最优解:复用业务服务层,避免重复配置+跳过HTTP损耗
既然你已经有了Core(领域模型+接口)和Infrastructure(接口实现)的分层,完全可以让Blazor Server直接依赖这两个类库,复用业务逻辑层,同时解决重复配置的问题:
步骤1:封装DI配置到扩展方法
在Infrastructure类库中创建一个扩展方法,把所有需要注册的服务(DbContext、仓储实现、业务服务等)统一封装:
// Infrastructure类库中的扩展方法 public static class InfrastructureServiceExtensions { public static IServiceCollection AddInfrastructureServices(this IServiceCollection services, IConfiguration configuration) { // 配置DbContext services.AddDbContext<AppDbContext>(options => options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"))); // 注册仓储实现 services.AddScoped<IUserRepository, UserRepository>(); services.AddScoped<IOrderRepository, OrderRepository>(); // 注册其他业务服务 services.AddScoped<IUserService, UserService>(); return services; } }
步骤2:在WebAPI和Blazor中复用配置
不管是WebAPI还是Blazor Server的Program.cs,只需要一行代码即可完成所有基础设施服务的注册:
// WebAPI/Blazor Server的Program.cs builder.Services.AddInfrastructureServices(builder.Configuration);
这样就完全避免了重复编写组合根的问题,后续Infrastructure的配置更新,只需要修改扩展方法,两个项目自动同步。
步骤3:Blazor直接调用业务服务
在Blazor组件中直接注入Core层定义的业务接口,调用业务逻辑,完全跳过HTTP请求:
@inject IUserService UserService <h3>用户列表</h3> @if (Users != null) { foreach (var user in Users) { <p>@user.Name</p> } } @code { private List<User>? Users; protected override async Task OnInitializedAsync() { Users = await UserService.GetAllUsersAsync(); } }
什么时候需要调用WebAPI?
如果你的Blazor Server需要和WebAPI部署在不同的服务器(比如WebAPI在云服务器,Blazor Server在本地),或者未来计划支持Blazor WebAssembly(客户端运行,必须通过HTTP调用API),这时候才需要统一通过WebAPI来访问业务逻辑。但即便如此,也可以在Blazor中封装一个API客户端类,统一处理HTTP请求,避免重复编写HttpClient调用代码。
内容的提问来源于stack exchange,提问作者DM-98

