ASP.NET Core 6 Web API 中的三层架构
介绍
在本文中,我们将了解三层架构以及如何将数据访问层和业务访问层合并到项目中,以及这些层如何交互。
项目结构
我们在这个项目中使用了三层架构,分别是数据访问层、业务访问层和应用表示层。
表示层 (PL)
Presentation层是三层架构的最顶层,主要作用是把结果展示给用户,或者说,把我们从业务访问层获取的数据呈现出来,提供给用户。将结果提供给前端用户。
业务访问层 (BAL)
逻辑层与数据访问层和表示层交互以处理导致逻辑决策和评估的活动。该层的主要工作是处理其他层之间的数据。
数据访问层 (DAL)
该层的主要功能是访问和存储来自数据库的数据,并将数据到业务访问层的过程将数据根据用户请求传递到表示层。
配置这些层的步骤,
- 为数据访问层添加 Asp.net 的类库项目
- 右键单击该项目,然后转到添加新项目窗口,然后添加 Asp.net Core 类库项目。
- 现在添加数据访问层项目后,我们将添加业务访问层文件夹
- 添加Asp.Net Core for Business Access的类库项目
- 右键单击该项目,然后转到添加新项目窗口,然后添加 Asp.net Core 类库项目。
添加业务访问层和数据访问层后,首先要添加数据访问层和业务访问层的引用,这样才能看到项目结构。
如您所见,我们的项目现在有一个表示层、数据访问层和业务访问层。
添加项目的引用
现在,在表示层中,添加对数据访问层和业务访问层的引用。
右键单击表示层,然后单击添加 => 项目参考
通过选中两个复选框来添加参考
已为 DAL 和 BAL 添加了参考
现在我们将数据访问层项目引用添加到业务层。
- 右键单击业务访问层,然后单击添加按钮 => 项目引用
“请记住,我们已经在项目中包含了 DAL 和 BAL 引用,因此不要在业务层中再次添加 Presentation 层引用。我们只需要业务层中的 DAL 层引用”
BAL层增加了DAL的项目参考
数据访问层
数据访问层包含帮助业务访问层编写业务逻辑的方法,无论这些功能是否与访问或操作数据相关联。数据访问层的主要目标是与我们项目中的数据库和业务访问层进行交互。
结构将是这样的。
在这一层中,我们有以下文件夹。将这些文件夹添加到您的数据访问层
- Contacts
- Data
- Migrations
- Models
- Repositories
Contacts
在合同文件夹中,我们定义了具有以下功能的接口,这些功能与数据库一起执行所需的功能,例如
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JWTTokenAuthInAspNet6_DAL.Contracts {
public interface IRepository < T > {
public Task < T > Create(T _object);
public void Delete(T _object);
public void Update(T _object);
public IEnumerable < T > GetAll();
public T GetById(int Id);
}
}
Data
在 Data 文件夹中,我们有 Db Context Class 这个类对于从数据库中访问数据非常重要
Migration
Migration 文件夹包含有关我们在构建此项目期间执行的所有迁移的信息。Migration 文件夹包含有关我们在构建此项目期间执行的所有迁移的信息。
Model
我们的应用程序模型(包含特定领域的数据)和业务逻辑模型(将数据结构表示为公共属性、业务逻辑和方法)存储在 Model 文件夹中。
using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JWTTokenAuthInAspNet6_DAL.Models
{
public class AppUser: IdentityUser
{
public int Id { get; set; }
public string? Name { get; set; }
public string? AccountType { get; set; }
public string? PhoneNo { get; set; }
public string? Password { get; set; }
public string? ShopName { get; set; }
public string? BusinessType { get; set; }
public string? UserRole { get; set; }
public bool? IsDeleted { get; set; }
}
}
Repository
在 Repository 文件夹中,我们针对每个模型添加存储库类。我们使用实体框架编写与数据库通信的 CRUD 函数。我们添加了继承我们的接口的存储库类,该接口存在于我们的合约文件夹中。
using JWTTokenAuthInAspNet6_DAL.Contracts;
using JWTTokenAuthInAspNet6_DAL.Data;
using JWTTokenAuthInAspNet6_DAL.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JWTTokenAuthInAspNet6_DAL.Repositories {
public class RepositoryAppUser: IRepository < AppUser > {
private readonly AppDbContext _appDbContext;
private readonly ILogger _logger;
public RepositoryAppUser(ILogger < AppUser > logger) {
_logger = logger;
}
public async Task < AppUser > Create(AppUser appuser) {
try {
if (appuser != null) {
var obj = _appDbContext.Add < AppUser > (appuser);
await _appDbContext.SaveChangesAsync();
return obj.Entity;
} else {
return null;
}
} catch (Exception) {
throw;
}
}
public void Delete(AppUser appuser) {
try {
if (appuser != null) {
var obj = _appDbContext.Remove(appuser);
if (obj != null) {
_appDbContext.SaveChangesAsync();
}
}
} catch (Exception) {
throw;
}
}
public IEnumerable < AppUser > GetAll() {
try {
var obj = _appDbContext.AppUsers.ToList();
if (obj != null) return obj;
else return null;
} catch (Exception) {
throw;
}
}
public AppUser GetById(int Id) {
try {
if (Id != null) {
var Obj = _appDbContext.AppUsers.FirstOrDefault(x => x.Id == Id);
if (Obj != null) return Obj;
else return null;
} else {
return null;
}
} catch (Exception) {
throw;
}
}
public void Update(AppUser appuser) {
try {
if (appuser != null) {
var obj = _appDbContext.Update(appuser);
if (obj != null) _appDbContext.SaveChanges();
}
} catch (Exception) {
throw;
}
}
}
}
业务访问层
业务层与数据访问层通信,表示层逻辑层处理做出逻辑决策和评估的动作,该层的主要功能是处理周围层之间的数据。
我们在业务访问层中的项目结构将是这样的。
在这一层中,我们将有两个文件夹
- 扩展方法文件夹
- 和服务文件夹
在业务访问层,我们的服务与数据层和表示层等周围层进行通信。
服务
服务定义应用程序的业务逻辑。我们开发与数据层交互的服务,并将数据从数据层移动到表示层,从表示层移动到数据访问层。
例子
using JWTTokenAuthInAspNet6_DAL.Contracts;
using JWTTokenAuthInAspNet6_DAL.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JWTTokenAuthInAspNet6_BAL.Services {
public class ServiceAppUser {
public readonly IRepository < AppUser > _repository;
public ServiceAppUser(IRepository < AppUser > repository) {
_repository = repository;
}
//Create Method
public async Task < AppUser > AddUser(AppUser appUser) {
try {
if (appUser == null) {
throw new ArgumentNullException(nameof(appUser));
} else {
return await _repository.Create(appUser);
}
} catch (Exception) {
throw;
}
}
public void DeleteUser(int Id) {
try {
if (Id != 0) {
var obj = _repository.GetAll().Where(x => x.Id == Id).FirstOrDefault();
_repository.Delete(obj);
}
} catch (Exception) {
throw;
}
}
public void UpdateUser(int Id) {
try {
if (Id != 0) {
var obj = _repository.GetAll().Where(x => x.Id == Id).FirstOrDefault();
if (obj != null) _repository.Update(obj);
}
} catch (Exception) {
throw;
}
}
public IEnumerable < AppUser > GetAllUser() {
try {
return _repository.GetAll().ToList();
} catch (Exception) {
throw;
}
}
}
}
表示层
3-Tier架构的最上层是Presentation层,该层的主要功能是把结果给用户,或者简单来说就是把我们从业务访问层得到的数据展示出来,然后把结果给前端用户。
在表示层,我们这里有 asp.net 核心应用程序的默认模板,我们的应用程序结构将如下所示
表示层负责针对每个 HTTP 请求将结果提供给用户。这里我们有一个控制器,负责处理 HTTP 请求,并针对每个 HTTP 请求与业务层通信,从关联层获取获取数据,然后将其呈现给用户。
三层架构的优势
- 它使表示层、业务层和数据层之间的逻辑分离。
- 迁移到新环境的速度很快。
- 在这个模型中,每一层都是独立的,因此我们可以在每一层上设置不同的开发者,以便快速开发应用程序
- 易于维护和理解大型应用程序
- 业务层位于表示层和数据层之间,应用程序更安全,因为客户端无法直接访问数据库。
- 从业务层发送的流程数据在此级别进行验证。
- 来自表示层的已发布数据将在插入或更新数据库之前在业务层进行验证
- 可以在 BAL 层提供数据库安全性
- 在 BAL 层定义业务逻辑,然后在表示层的其他组件之间共享
- 易于应用面向对象的概念
- 易于更新 DAL 层提供的数据
三层架构的缺点
- 构建应用程序的一小部分需要大量时间
- 需要对面向对象编程有很好的理解
结论
在本文中,我们了解了三层架构以及三层之间如何交换数据,我们如何在项目中添加数据访问层业务访问层,并研究了这些层之间如何相互通信。
在下一篇文章中,我们将在 ASP.net Core Web API 中使用 3-Tier Architecture for JWT Token Authentication 开发项目。
常见问题FAQ
- 程序仅供学习研究,请勿用于非法用途,不得违反国家法律,否则后果自负,一切法律责任与本站无关。
- 请仔细阅读以上条款再购买,拍下即代表同意条款并遵守约定,谢谢大家支持理解!