C# .NET 8 三层架构实战:电商订单模块 UI/BLL/DAL 完整代码实现 C# .NET 8 三层架构实战电商订单模块 UI/BLL/DAL 完整代码实现电商系统开发中订单模块作为核心业务场景其代码结构的清晰度和可维护性直接影响系统长期演化能力。本文将基于.NET 8平台通过一个完整的订单创建与查询流程演示如何运用三层架构实现业务逻辑的解耦与复用。不同于理论概念的泛泛而谈我们直接从Visual Studio解决方案创建开始逐步构建可运行的代码实例。1. 解决方案结构与项目初始化首先在Visual Studio 2022中创建空白解决方案ECommerceOrderSystem并添加以下四个类库项目ECommerceOrderSystem.sln ├── OrderSystem.UI (ASP.NET Core Web API) ├── OrderSystem.BLL (.NET Standard 2.1) ├── OrderSystem.DAL (.NET Standard 2.1) └── OrderSystem.Model (.NET Standard 2.1)各项目引用关系应严格遵循分层原则UI层引用BLL和ModelBLL层引用DAL和ModelDAL层仅引用Model!-- OrderSystem.UI.csproj 示例引用配置 -- ItemGroup ProjectReference Include..\OrderSystem.BLL\OrderSystem.BLL.csproj / ProjectReference Include..\OrderSystem.Model\OrderSystem.Model.csproj / /ItemGroup实体类设计是三层架构的基础在Model项目中定义核心业务对象// OrderSystem.Model/Entities/Order.cs public class Order { public int Id { get; set; } public string OrderNumber { get; set; } public DateTime CreateTime { get; set; } public decimal TotalAmount { get; set; } public OrderStatus Status { get; set; } public ListOrderItem Items { get; set; } } public enum OrderStatus { Pending, Paid, Shipped, Completed, Cancelled }2. 数据访问层(DAL)实现DAL层采用Repository模式封装所有数据库操作。我们使用Entity Framework Core 8作为ORM框架// OrderSystem.DAL/Repositories/OrderRepository.cs public class OrderRepository : IOrderRepository { private readonly OrderDbContext _context; public OrderRepository(OrderDbContext context) { _context context; } public async TaskOrder GetByIdAsync(int id) { return await _context.Orders .Include(o o.Items) .FirstOrDefaultAsync(o o.Id id); } public async Task CreateAsync(Order order) { order.OrderNumber GenerateOrderNumber(); order.CreateTime DateTime.UtcNow; await _context.Orders.AddAsync(order); await _context.SaveChangesAsync(); } private string GenerateOrderNumber() { return $ORD-{DateTime.UtcNow:yyyyMMddHHmmss}-{Guid.NewGuid().ToString()[..4]}; } }DbContext配置需要特别注意性能优化// OrderSystem.DAL/OrderDbContext.cs public class OrderDbContext : DbContext { public DbSetOrder Orders { get; set; } public DbSetOrderItem OrderItems { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder options) { // 实际项目中应从配置读取连接字符串 options.UseSqlServer(Server.;DatabaseECommerceOrder;Trusted_ConnectionTrue;) .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.EntityOrder(entity { entity.HasIndex(o o.OrderNumber).IsUnique(); entity.Property(o o.TotalAmount).HasPrecision(18, 2); }); } }3. 业务逻辑层(BLL)设计BLL层需要处理核心业务规则验证。以下是订单创建的典型业务逻辑// OrderSystem.BLL/Services/OrderService.cs public class OrderService : IOrderService { private readonly IOrderRepository _orderRepository; private readonly IInventoryService _inventoryService; public OrderService(IOrderRepository orderRepository, IInventoryService inventoryService) { _orderRepository orderRepository; _inventoryService inventoryService; } public async TaskOrderResult CreateOrderAsync(OrderRequest request) { // 验证商品库存 var inventoryCheck await _inventoryService .CheckInventoryAsync(request.Items); if (!inventoryCheck.IsAvailable) { return OrderResult.Failed(部分商品库存不足); } // 构建订单实体 var order new Order { Status OrderStatus.Pending, Items request.Items.Select(i new OrderItem { ProductId i.ProductId, Quantity i.Quantity, UnitPrice i.UnitPrice }).ToList(), TotalAmount request.Items.Sum(i i.Quantity * i.UnitPrice) }; // 持久化订单 await _orderRepository.CreateAsync(order); // 扣减库存 await _inventoryService.ReduceInventoryAsync(request.Items); return OrderResult.Success(order.Id); } }业务异常处理是BLL层的重要职责public class OrderResult { public bool IsSuccess { get; } public string ErrorMessage { get; } public int? OrderId { get; } private OrderResult(bool isSuccess, string errorMessage, int? orderId) { IsSuccess isSuccess; ErrorMessage errorMessage; OrderId orderId; } public static OrderResult Success(int orderId) new(true, null, orderId); public static OrderResult Failed(string error) new(false, error, null); }4. 表现层(UI)实现在ASP.NET Core Web API中我们通过Controller组织接口// OrderSystem.UI/Controllers/OrdersController.cs [ApiController] [Route(api/[controller])] public class OrdersController : ControllerBase { private readonly IOrderService _orderService; public OrdersController(IOrderService orderService) { _orderService orderService; } [HttpPost] public async TaskIActionResult CreateOrder([FromBody] OrderRequest request) { var result await _orderService.CreateOrderAsync(request); if (!result.IsSuccess) { return BadRequest(new { result.ErrorMessage }); } return CreatedAtAction( nameof(GetOrder), new { id result.OrderId }, new { OrderId result.OrderId }); } [HttpGet({id})] public async TaskIActionResult GetOrder(int id) { var order await _orderService.GetOrderByIdAsync(id); if (order null) { return NotFound(); } return Ok(order); } }依赖注入配置确保各层正确衔接// OrderSystem.UI/Program.cs builder.Services.AddScopedIOrderService, OrderService(); builder.Services.AddScopedIOrderRepository, OrderRepository(); builder.Services.AddDbContextOrderDbContext(options options.UseSqlServer(builder.Configuration.GetConnectionString(Default)));5. 层间通信优化与高级技巧DTO模式可有效隔离层间数据传递// OrderSystem.Model/DTOs/OrderDto.cs public class OrderDto { public int Id { get; set; } public string OrderNumber { get; set; } public string Status { get; set; } public decimal TotalAmount { get; set; } public ListOrderItemDto Items { get; set; } } // BLL层转换方法示例 public OrderDto ConvertToDto(Order order) { return new OrderDto { Id order.Id, OrderNumber order.OrderNumber, Status order.Status.ToString(), TotalAmount order.TotalAmount, Items order.Items.Select(i new OrderItemDto { ProductId i.ProductId, Quantity i.Quantity, UnitPrice i.UnitPrice }).ToList() }; }性能优化策略在实际项目中尤为重要优化点实施方法预期效果数据库查询使用AsNoTracking()减少内存占用批量操作实现批量插入接口提高数据写入速度缓存策略在BLL层引入Redis缓存降低数据库负载异步编程全链路async/await提高系统吞吐量// 批量插入优化示例 public async Task CreateBatchAsync(IEnumerableOrder orders) { await _context.BulkInsertAsync(orders, options { options.BatchSize 1000; options.InsertKeepIdentity true; }); }6. 单元测试策略各层测试重点应有不同侧重// OrderSystem.BLL.Tests/OrderServiceTests.cs public class OrderServiceTests { [Fact] public async Task CreateOrder_ShouldFail_WhenInventoryInsufficient() { // 准备Mock对象 var mockRepo new MockIOrderRepository(); var mockInventory new MockIInventoryService(); mockInventory.Setup(x x.CheckInventoryAsync(It.IsAnyListOrderItem())) .ReturnsAsync(new InventoryCheckResult { IsAvailable false }); // 测试执行 var service new OrderService(mockRepo.Object, mockInventory.Object); var result await service.CreateOrderAsync(new OrderRequest { /* 测试数据 */ }); // 验证结果 Assert.False(result.IsSuccess); mockRepo.Verify(x x.CreateAsync(It.IsAnyOrder()), Times.Never); } }测试金字塔在分层架构中的实践UI层测试(20%) / \ / \ BLL层测试(30%) DAL层测试(50%)7. 架构演进与扩展当业务复杂度增加时可考虑以下演进方向引入领域驱动设计将BLL层细分为Application Service和Domain Service事件驱动架构通过领域事件解耦订单创建与后续处理流程CQRS模式分离订单查询与命令处理路径// 领域事件示例 public class OrderCreatedEvent { public int OrderId { get; } public DateTime OccurredOn { get; } DateTime.UtcNow; public OrderCreatedEvent(int orderId) { OrderId orderId; } } // 在OrderService中发布事件 await _eventBus.Publish(new OrderCreatedEvent(order.Id));实际项目开发中三层架构的边界维护需要团队共识。我曾在一个电商平台重构项目中通过引入静态代码分析工具来强制执行分层规则!-- Directory.Build.props 示例 -- ItemGroup PackageReference IncludeNetArchTest.Rules Version1.3.0 / /ItemGroup !-- 架构测试用例 -- [Fact] public void DAL_Should_Not_DependOn_UI() { var result Types.InAssembly(typeof(OrderRepository).Assembly) .ShouldNot() .HaveDependencyOn(OrderSystem.UI) .GetResult(); Assert.True(result.IsSuccessful); }