如何使用 EF Core 代码优先迁移为 ASP.NET Core MVC 配置 N 层架构

Posted

技术标签:

【中文标题】如何使用 EF Core 代码优先迁移为 ASP.NET Core MVC 配置 N 层架构【英文标题】:How to configure N-tier architecture for ASP.NET Core MVC with EF Core code first migrations 【发布时间】:2022-01-08 05:06:49 【问题描述】:

如果我的一些逻辑有缺陷,我深表歉意,因为我是 ASP.NET Core 中规模应用程序开发的新手。我正在使用 Entity Framework Core(代码优先)和 ASP.NET Core 5 MVC,并且希望能够将我的项目分成 3 个不同的层:

    数据层(数据访问层)

这将包含迁移、ApplicationDbContext 和代表我程序中实体的 POCO。

    服务层

这将包含用于从数据层访问数据的接口及其具体实现。

// For example
public UserService : IUserService

   public async Task<IEnumerable<User>> GetAllUsers()
   
      // ApplicationDbContext injected in constructor and stored in readonly _context variable
      await _context.Users.ToListAsync();
   

    表示层(ASP.NET Core MVC UI)

这将包含典型的 MVC 事物,例如视图模型、控制器和 Razor 视图。在这一层中,我想将服务注入到控制器中,例如:

public class HomeController : Controller

   private readonly IUserService _userService;

   public HomeController(IUserService userService)
   
     _userService = userService;
   
   
   public async Task<IActionResult> Index()
   
       return await _userService.GetAllUsers();
   

这种架构的理想结果是,在某些时候我们可以改变我们正在使用的 ORM 和数据库的底层实现,而表示层不必改变。

然而,目前,我仍然需要在表示层启动时在依赖注入容器中注册 AppDbContext(因为 UserService 依赖于 ApplicationDbContext 并且 DI 容器正在尝试解决此问题) .

services.AddDbContext<ApplicationDbContext>(options => 
    options.UseSqlServer(Configuration.GetConnectionString("MyConnectionString")));
services.AddScoped <IUserService, UserService>();

有没有办法可以从表示层中删除所有数据访问引用(包括DbContext),以便在 ORM(EF Core)或使用的底层数据库(例如 SQL Server for mysql)发生更改时,表示层不需要更新和重新部署?

【问题讨论】:

我建议你看看“存储库模式”和“洋葱架构” "然而,目前我仍然需要在表示层启动时在依赖注入容器中注册 AppDbContext(因为 UserService 依赖于 ApplicationDbContext 并且 DI 容器正在尝试解决这个问题) 。” -> 不,你没有。在任何适当的层中创建一个扩展方法,例如 public static IServiceCollection InjectInfrastructureServices(this IServiceCollection services),然后从 Startup 调用它 啊,这似乎成功了,我没想到要扩展 IserviceCollection。我最终在服务层中添加了扩展,并且必须将配置从启动传递给它。谢谢 【参考方案1】:

实际上,在您的应用程序投入生产后在 DB 下进行更改的情况很少发生,如果发生这种情况,您会更改相关代码或可能重新编写整个应用程序。 无论如何,看看这个以实现关注点分离https://dotnet.microsoft.com/learn/aspnet/architecture

仅在 startup.cs 中为 DI 目的引用 UI 层中的数据层是可以的。 在服务层创建实体,以便 UI 层可以将实体映射到模型

【讨论】:

感谢您对典型后期制作行为的洞察!当我有机会时,我会通读那本电子书。将这些实体提升到一个共同项目中是否有益? (或者将实体保留在数据层中,然后为 DTO 使用公共/服务层)? 使用 .NET Core 的干净架构,您不必拥有单独的数据层和域层。您可以拥有 UI、ApplicationCore 和 Infrastructure 层。应用程序核心层将拥有实体、服务等,而基础设施将拥有 DB Context 的实际实现。看看这个干净的架构docs.microsoft.com/en-us/dotnet/architecture/…(向下滚动以了解干净的架构实现)

以上是关于如何使用 EF Core 代码优先迁移为 ASP.NET Core MVC 配置 N 层架构的主要内容,如果未能解决你的问题,请参考以下文章

用于 ASP.NET Core 应用程序的 EF Code First 迁移替代方案

如何使用 ASP.NET Core 设置 EF6 迁移

我可以将依赖项注入迁移(使用 EF-Core 代码优先迁移)吗?

如何使用 EF Core 在 ASP.NET Core 中取消应用迁移

EF Core - 代码优先迁移:关键字“NOT”附近的语法不正确

text EF Core 2 - 代码优先迁移