分层架构下如何配置DI避免UI层引用数据层并完成依赖注册
实现方案
你可以通过分层注册DI扩展方法的方式满足需求,全程不需要WebApi层直接感知DataAccess层的具体实现,具体操作步骤如下:
1. 调整项目引用规则
- WebApi层仅引用Services层,无需添加DataAccess层的项目引用
- Services层仅引用DataAccess层,只依赖DataAccess对外暴露的抽象接口,不绑定具体实现类
- DataAccess层无需引用其他业务层级
2. DataAccess层封装本层依赖注册逻辑
在DataAccess层新建静态扩展类,把所有仓储的注册逻辑内聚在本层内部,对外只暴露扩展方法入口:
using Microsoft.Extensions.DependencyInjection; namespace DataAccess; public static class DataAccessServiceExtensions { // 注册正式环境仓储实现 public static IServiceCollection AddDataAccess(this IServiceCollection services) { services.AddScoped<IUserRepo, UserRepo>(); services.AddScoped<IProductRepo, ProductRepo>(); // EF Core的DbContext注册等数据层相关配置也可以放在这里 services.AddDbContext<YourDbContext>(opt => { // 你的数据库连接配置逻辑 }); return services; } // 注册测试环境仓储实现 public static IServiceCollection AddTestDataAccess(this IServiceCollection services) { services.AddScoped<IUserRepo, UserTestRepo>(); services.AddScoped<IProductRepo, ProductTestRepo>(); return services; } }
3. Services层封装本层依赖注册逻辑
同理在Services层新建静态扩展类,注册所有业务服务的实现:
using Microsoft.Extensions.DependencyInjection; namespace Services; public static class ServicesServiceExtensions { public static IServiceCollection AddBusinessServices(this IServiceCollection services) { services.AddScoped<IUserService, UserService>(); services.AddScoped<IProductService, ProductService>(); return services; } }
4. WebApi启动类完成最终注册
只需要在WebApi的启动类(Program.cs/Startup.cs)中调用上面两个扩展方法即可,全程不需要直接引用任何仓储相关的具体实现类型:
var builder = WebApplication.CreateBuilder(args); // 注册业务层服务 builder.Services.AddBusinessServices(); // 注册数据层实现,测试环境可替换为AddTestDataAccess() builder.Services.AddDataAccess(); // 其他WebApi配置逻辑 var app = builder.Build(); // 中间件配置逻辑 app.Run();
核心逻辑说明
- 各层的依赖注册逻辑完全内聚在本层,上层只需要调用扩展方法即可,不需要感知下层的实现细节
- WebApi层全程不需要接触任何仓储相关的类型,完全符合分层隔离的要求
- 切换正式/测试仓储实现只需要修改WebApi中调用的扩展方法,不需要改动其他层代码
内容的提问来源于stack exchange,提问作者user3953989
相关产品推荐
相关产品推荐

