持久化事件订阅
持久化事件订阅是指实体插入、修改或删除时,会通知订阅器做相应的处理。事件会在动作发生之前及之后进行触发。使用订阅器可以使业务逻辑解耦,比如删除数据前的逻辑判断,数据创建成功后的各种协调处理等等。
PersistentSubscriber
和 AsyncPersistentSubscriber
类分别是同步订阅器和异步订阅器抽象类,你继承此类实现方法的重写即可。如下所示:
private class MySubscriber : PersistentSubscriber
{
protected override bool OnBeforeCreate(IEntity entity)
{
return true;
}
protected override void OnAfterCreate(IEntity entity)
{
}
protected override bool OnBeforeUpdate(IEntity entity)
{
return true;
}
protected override void OnAfterUpdate(IEntity entity)
{
}
protected override bool OnBeforeRemove(IEntity entity)
{
return true;
}
protected override void OnAfterRemove(IEntity entity)
{
}
protected override bool OnBeforeBatch(IEnumerable<IEntity> entities, PersistentOperator operater)
{
return true;
}
protected override void OnAfterBatch(IEnumerable<IEntity> entities, PersistentOperator operater)
{
}
protected override void OnCreate(Type entityType)
{
}
protected override void OnUpdate(Type entityType)
{
}
protected override void OnRemove(Type entityType)
{
}
}
OnBeforeCreate 在实体插入之前触发,如果你想阻止实体插入,则可以返回 false。
OnAfterCreate 在实体插入之后触发。
OnBeforeUpdate 在实体更新之前触发,如果你想阻止实体更新,则可以返回 false。
OnAfterUpdate 在实体更新之后触发。
OnBeforeRemove 在实体删除之前触发,如果你想阻止实体删除,则可以返回 false。
OnAfterRemove 在实体删除之后触发。
OnBeforeBatch 在批量操作之前触发,根据
PersistentOperator
判断是新增、修改还是删除。如果你想阻止批量操作,则可以返回 false。OnAfterBatch 在批量操作之后触发,根据
PersistentOperator
判断是新增、修改还是删除。
OnCreate、OnUpdate、OnRemove 仅仅捕获实体类型,不针对具体的实体对象。OnBeforeBatch 和 OnAfterBatch 时也会触发相应的方法。
实现完订阅器后,使用 PersistentSubscribeManager
类的 AddSubscriber 或 AddAsyncSubscriber 方法添加订阅器。如下所示:
[TestMethod]
public void TestAddSubscriber()
{
PersistentSubscribeManager.AddSubscriber(s => new MySubscriber().Accept(s));
//PersistentSubscribeManager.AddAsyncSubscriber(s => new MyAsyncSubscriber().AcceptAsync(s));
}
.Net Core 应用程序中,你可以在 Startup.ConfigureServices 方法里使用扩展方法 AddPersistentSubscriber 或 AddAsyncPersistentSubscriber 来添加订阅器。如下所示:
namespace demo
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddFireasy(Configuration).AddIoc();
services.AddSubscriber<MySubscriber>();
//services.AddAsyncSubscriber<MyAsyncSubscriber>();
}
}
}
使用这种方式注入的订阅器,是支持构造函数注入的,你可以在构造函数里将 EntityContext
实例注入进来。
AddSubscriber 和 AddAsyncSubscriber 方法支持 EntityContext
和 PersistentSubject
过滤,使得管理订阅管理器能够决定哪些订阅器可以接收事件消息。如下所示:
namespace demo
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddFireasy(Configuration).AddIoc();
//DbContext 触发,只订阅 Org 实体的相关消息
services.AddSubscriber<DbContext, MySubscriber>(s => s.EntityType == typeof(Org));
}
}
}
默认是关闭事件订阅的,你可以在 EntityContextOptions
参数里设置 NotifyEvents 开启,请参阅 配置 EntityContextOptions。开启后,你可以需要关闭的地方使用 DisableSubscribeScope
对象来暂时关闭订阅通知。如下所示:
[TestMethod]
public void TestDisableSubscriber()
{
using (var db = new DbContext())
using (var scope = new DisableSubscribeScope(
PersistentEventType.BeforeCreate,
PersistentEventType.AfterCreate))
{
var product = db.Products.Get(1);
product.ProductName = "fireasy";
db.Products.Update(product);
}
}
DisableSubscribeScope
的构造函数可以传入需要禁用的事件类型,如果不指定则禁用所有事件。