NetCore结合CAP事件总线实现分布式事务——过滤器(3)
一、过滤器
在 5.1.0 版本中,我们支持了在订阅者中添加过滤器。在过去,我们通过对第三方 AOP 组件提供支持来做到这一点,例如我们写了一篇博客 来描述如何在 CAP 5.0 版本中使用 Castle 来对订阅方法进行拦截,但了这种方式存在一些缺点,例如无法方便的在代理类中进行构造函数注入以及方法需要设定为 virtual 另外还有拦截器生命周期控制等问题。所以我们引入了对订阅者过滤器的支持,以使在某些场景(如事务处理,日志记录等)中变得容易。
版本支持
需要创建net6或者net5的项目,
using DotNetCore.CAP 5.1.0及以上;
二.配置信息
Promgram.cs
using _03_Subscriber;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
//获得配置
IConfigurationRoot configuration = builder.Configuration;
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
//注入数据库
builder.Services.AddDbContext<SubDBContext>(options => options.UseSqlServer(configuration.GetConnectionString("AngelDBContext")));
builder.Services.AddCap(x =>
{
x.UseEntityFramework<SubDBContext>();
x.UseRabbitMQ(rb =>
{
rb.HostName = "localhost";
rb.UserName = "admin";
rb.Password = "admin";
rb.Port = 5672;
rb.VirtualHost = "Angel2022";
rb.ExchangeName = "AngelCapExchange";
});
x.UseDashboard();//使用Cap可视化面板
//添加过滤器
}).AddSubscribeFilter<MyCapFilter>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthorization();
app.MapControllers();
app.Run();
过滤器方法 MyCapFilter
继承ISubsriFilter从而对订阅消息,实现切面编程
using DotNetCore.CAP.Filter;
using System;
namespace _03_Subscriber
{
public class MyCapFilter : ISubscribeFilter
{
public void OnSubscribeExecuting(ExecutingContext context)
{
// 订阅方法执行前
Console.WriteLine("订阅方法执行前");
}
public void OnSubscribeExecuted(ExecutedContext context)
{
// 订阅方法执行后
Console.WriteLine("订阅方法执行后");
}
public void OnSubscribeException(ExceptionContext context)
{
// 订阅方法执行异常
Console.WriteLine("订阅方法执行异常");
}
}
}
SubDBContext
using Microsoft.EntityFrameworkCore;
namespace _03_Subscriber
{
public class SubDBContext : DbContext
{
public SubDBContext()
{
}
public SubDBContext(DbContextOptions<SubDBContext> options) : base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
}
}
}
连接字符串
"ConnectionStrings": { //连接字符串
"AngelDBContext": "data source=.;initial catalog=AngelCapDB;User ID=sa;Password=123456;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"
}
#region 回调
[NonAction]
[CapSubscribe("angel")]
public Person ReceiveMsg(Person str)
{
if (str != null)
{
Console.WriteLine($"接收{str.Id}");
_log.LogInformation($"我是订阅者,收到的内容为:{str.Id},{str.Name}");
return str;
}
throw new Exception();
}
[NonAction]
[CapSubscribe("image")]
public void CallBackMsg(Person str)
{
if (str != null)
{
Console.WriteLine($"回调{str.Id}");
_log.LogInformation($"我是回调,回调的内容为:{str.Id},{str.Name}");
}
}