如何为使用EF Core Code First迁移的ASP.NET Core MVC配置N层架构
实现方案
完全可以实现你要的隔离效果,核心思路是把所有底层依赖的注册逻辑下沉到服务层/数据层,通过扩展方法封装注册逻辑,表现层完全不需要感知数据访问相关的实现细节。
步骤1:调整项目依赖关系
首先梳理项目的引用链,彻底切断表现层和数据访问层的直接引用:
- 「MyApp.Entities」(可选,也可以合并到数据层):存放所有POCO实体类,无外部业务依赖,被其他三层引用
- 「MyApp.DataAccess」:数据访问层,存放
ApplicationDbContext、迁移文件、ORM相关配置,引用Entities项目,安装EF Core对应数据库的Nuget包 - 「MyApp.Services」:服务层,存放服务接口+实现,引用DataAccess和Entities项目
- 「MyApp.Web」:表现层,仅引用Services项目,不要安装任何EF Core相关Nuget包,也不要直接引用DataAccess项目
步骤2:封装依赖注入扩展方法
在服务层新增静态扩展类,把所有底层依赖的注册逻辑全部封装到内部,不对外暴露DbContext相关的实现:
using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using MyApp.DataAccess; namespace MyApp.Services; public static class ServiceCollectionExtensions { public static IServiceCollection AddAppBusinessServices(this IServiceCollection services, IConfiguration configuration) { // DbContext注册完全封装在服务层内部,表现层无感知 services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(configuration.GetConnectionString("MyConnectionString"))); // 所有业务服务的注册统一在这里管理 services.AddScoped<IUserService, UserService>(); // 其他服务注册同理 return services; } }
步骤3:表现层仅调用扩展方法完成注册
表现层的Startup.cs/Program.cs中不需要写任何DbContext相关的代码,只需要调用上面封装好的扩展方法即可:
// 仅需这一行完成所有业务服务的注册,无任何数据访问相关代码 services.AddAppBusinessServices(Configuration);
更换ORM/数据库的操作流程
按照以上结构实现后,更换数据库或者ORM完全不需要修改表现层的任何代码,甚至不需要重新编译表现层项目:
- 切换数据库(比如SQL Server换MySQL):仅修改DataAccess层扩展方法中的
UseSqlServer为UseMySql,更新EF Core MySQL的Nuget包,替换DataAccess和Services的dll即可 - 更换ORM(比如EF Core换Dapper):重新实现所有服务接口(比如
DapperUserService实现IUserService),修改扩展方法中的服务注册实现类,替换DataAccess和Services的dll即可
内容的提问来源于stack exchange,提问作者Stix
相关产品推荐
相关产品推荐

