CAP
- CAP docs看到更多详细资料。
- CAP 视频教程,学习如何在项目中集成CAP。
- GitHub源码:https://github.com/dotnetcore/cap
示例代码:https://github.com/dotnetcore/CAP/tree/master/samples
过滤器
在过去,CAP 通过对第三方 AOP 组件提供支持来做到这一点,但了这种方式存在一些缺点,例如无法方便的在代理类中进行构造函数注入以及方法需要设定为 virtual 另外还有拦截器生命周期控制等问题。
CAP引入了对订阅者过滤器的支持,以使在某些场景(如事务处理,日志记录等)中变得容易。自定义过滤器
创建一个过滤器类,并继承 SubscribeFilter 抽象类。 ```csharp public class MyCapFilter: SubscribeFilter { public override void OnSubscribeExecuting(ExecutingContext context) {
// 订阅方法执行前
}
public override void OnSubscribeExecuted(ExecutedContext context) {
// 订阅方法执行后
}
public override void OnSubscribeException(ExceptionContext context) {
// 订阅方法执行异常
} }
在一些场景中,如果想终止订阅者方法执行,可以在 OnSubscribeExecuting 中抛出异常,并且在 OnSubscribeException 中选择忽略该异常。<br />通过在 ExceptionContext 中设置 context.ExceptionHandled = true 来忽略异常。```csharppublic override void OnSubscribeException(ExceptionContext context){context.ExceptionHandled = true;}
services.AddCap(opt =>{// ***}.AddSubscribeFilter<MyCapFilter>();
过滤器示例
创建一个CAP.Filter.Demo项目,使用CAP之消息的项目代码,
Install-Package DotNetCore.CAPInstall-Package DotNetCore.CAP.InMemoryStorageInstall-Package Savorboard.CAP.InMemoryMessageQueue
创建一个过滤器类,并继承 SubscribeFilter 抽象类。
using DotNetCore.CAP.Filter;namespace CAP.Filter.Demo.Filter;public class MyCapFilter : SubscribeFilter{public override void OnSubscribeExecuting(ExecutingContext context){// 订阅方法执行前Console.WriteLine("订阅方法执行前");}public override void OnSubscribeExecuted(ExecutedContext context){// 订阅方法执行后Console.WriteLine("订阅方法执行后");}public override void OnSubscribeException(ExceptionContext context){// 订阅方法执行异常Console.WriteLine("订阅方法执行异常");//忽略异常//context.ExceptionHandled = true;}}
builder.Services.AddCap(config =>{config.UseInMemoryMessageQueue(); //配置一个消息队列config.UseInMemoryStorage(); //配置一个事件存储}).AddSubscribeFilter<MyCapFilter>();//配置过滤器
公共部分
using Microsoft.AspNetCore.Mvc;namespace CAP.Filter.Demo.Controllers;/// <summary>/// 基础控制器/// </summary>[Route("api/[area]/[controller]/[action]")][ApiController]public abstract class BaseController : ControllerBase{}
using Microsoft.AspNetCore.Mvc;namespace CAP.Filter.Demo.Controllers.Order;/// <summary>/// 域控制器/// </summary>[Area("Order")]public abstract class AreaController : BaseController{}
发布消息
新建立一个PublishController
using DotNetCore.CAP;using Microsoft.AspNetCore.Mvc;using System.Text.Json;namespace CAP.Filter.Demo.Controllers.Order;/// <summary>/// 发送消息/// </summary>public class PublishController : AreaController{ICapPublisher _capBus;public PublishController(ICapPublisher capBus){_capBus = capBus;}/// <summary>/// 订单处理示例/// </summary>/// <returns></returns>[HttpGet]public IActionResult PublisherMessage(){Console.WriteLine("订单处理示例");//商品数量扣除调用模拟的ConsumerController的place.order.qty.deducted_capBus.Publish("place.order.qty.deducted",contentObj: new { OrderId = 1234, ProductId = 23255, Qty = 1 },//当商品数量成功扣除时将状态标记为 succeeded ,否则为 failedcallbackName: "place.order.mark.status");return Ok();}/// <summary>/// 当商品数量成功扣除时将状态标记为 succeeded ,否则为 failed/// </summary>/// <param name="param"></param>[NonAction]//表示控制器方法不是动作方法[CapSubscribe("place.order.mark.status")]public void MarkOrderStatus(JsonElement param){var orderId = param.GetProperty("OrderId").GetInt32();var isSuccess = param.GetProperty("IsSuccess").GetBoolean();if (isSuccess){// mark order status to succeeded}else{// mark order status to failed}}}
处理消息
新建立一个ConsumerController
using DotNetCore.CAP;using Microsoft.AspNetCore.Mvc;using System.Text.Json;namespace CAP.Filter.Demo.Controllers.Order;/// <summary>/// 处理消息/// </summary>[ApiController]public class ConsumerController : ControllerBase{/// <summary>/// 订阅方法-商品数量扣除处理/// </summary>/// <param name="param"></param>/// <returns></returns>[NonAction]//表示控制器方法不是动作方法[CapSubscribe("place.order.qty.deducted")]public object DeductProductQty(JsonElement param){Console.WriteLine("商品数量扣除处理被调用");var orderId = param.GetProperty("OrderId").GetInt32();var productId = param.GetProperty("ProductId").GetInt32();var qty = param.GetProperty("Qty").GetInt32();//business logicreturn new { OrderId = orderId, IsSuccess = true };}}


