如何使用 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 迁移替代方案
我可以将依赖项注入迁移(使用 EF-Core 代码优先迁移)吗?
如何使用 EF Core 在 ASP.NET Core 中取消应用迁移