调用API时触发事件:如何在POST接口中触发OnOrderCreation方法
有两种实现方式,按需选择即可:
方式一:直接调用(适合只有一个通知逻辑、不需要扩展多个订阅者的场景)
你可以直接构造事件参数后调用目标方法即可,注意你现有代码有两个问题要修复:
- 实例化
OrderNotificationService时漏传了构造函数要求的IUnitOfWork参数 OnOrderCreation目前是async void签名,异常无法被外层捕获,容易引发未处理异常导致程序崩溃,建议调整为返回Task
调整后的代码:
首先修改接口和实现的返回值:
// 调整接口定义 public interface IOrderCreatedService { Task OnOrderCreation(object sender, OrderCreationEvents args); } // 调整实现类方法签名 public class OrderNotificationService : IOrderCreatedService { private readonly IUnitOfWork _unitOfWork; public OrderNotificationService(IUnitOfWork unitOfWork) { _unitOfWork = unitOfWork; } public async Task OnOrderCreation(object sender, OrderCreationEvents args) { var note = new Notification { CustomerId = args.CustomerId, PickUpLocation = args.PickUpLocation }; await _unitOfWork.Notifications.Insert(note); await _unitOfWork.Save(); } }
然后修改Create接口逻辑:
[HttpPost] public async Task<IActionResult> Create(OrderIDTO orderIDTO) { var order = new Order {...}; await _unitOfWork.Orders.Insert(order); // 先保存订单,确保订单落库后再触发通知 await _unitOfWork.Save(); // 构造事件参数 var eventArgs = new OrderCreationEvents(order.PickUpLocation, order.CustomerId); // 实例化通知服务 var notificationService = new OrderNotificationService(_unitOfWork); // 触发通知方法 await notificationService.OnOrderCreation(this, eventArgs); return RedirectToAction("index"); }
方式二:标准事件发布订阅(适合后续需要扩展多个订单创建监听逻辑的场景)
如果你希望用标准的事件机制解耦,不需要在Create方法里硬编码调用各个监听服务,可以按以下步骤改造:
- 在控制器内定义订单创建事件
- 在控制器构造函数中注册订阅者
- 订单保存成功后触发事件即可
调整后的代码:
public class OrderController : Controller { private readonly IUnitOfWork _unitOfWork; // 定义订单创建事件 public event EventHandler<OrderCreationEvents> OrderCreated; public OrderController(IUnitOfWork unitOfWork) { _unitOfWork = unitOfWork; // 注册通知服务为事件订阅者,后续新增订阅者只需要在这里加一行即可 OrderCreated += new OrderNotificationService(_unitOfWork).OnOrderCreation; } [HttpPost] public async Task<IActionResult> Create(OrderIDTO orderIDTO) { var order = new Order {...}; await _unitOfWork.Orders.Insert(order); await _unitOfWork.Save(); // 触发事件,所有订阅者都会自动执行对应逻辑 OrderCreated?.Invoke(this, new OrderCreationEvents(order.PickUpLocation, order.CustomerId)); return RedirectToAction("index"); } }
内容的提问来源于stack exchange,提问作者nour
相关产品推荐
相关产品推荐

