在2015年7月16日,XCode新增了实体处理模块IEntityModule,用于拦截实体对象添删改操作。
该接口参考IHttpModule设计理念,横切在实体对象的关键生命周期之中,以达到多实体类通用处理的效果。比如为多个实体类增加假删除等特色功能。
/// <summary>实体处理模块</summary>
public interface IEntityModule
{
/// <summary>为指定实体类初始化模块,返回是否支持</summary>
/// <param name="entityType"></param>
/// <returns></returns>
Boolean Init(Type entityType);
/// <summary>创建实体对象</summary>
/// <param name="entity"></param>
/// <param name="forEdit"></param>
void Create(IEntity entity, Boolean forEdit);
/// <summary>验证实体对象</summary>
/// <param name="entity"></param>
/// <param name="isNew"></param>
/// <returns></returns>
Boolean Valid(IEntity entity, Boolean isNew);
/// <summary>删除实体对象</summary>
/// <param name="entity"></param>
Boolean Delete(IEntity entity);
}
我们来看一段接口例程:
class TestModule : EntityModule
{
protected override Boolean OnInit(Type entityType)
{
return entityType == typeof(UserX);
}
protected override Boolean OnValid(IEntity entity, Boolean isNew)
{
if (isNew)
XTrace.WriteLine("新增实体 " + entity.GetType().Name);
else
XTrace.WriteLine("更新实体 " + entity.GetType().Name);
return base.OnValid(entity, isNew);
}
protected override Boolean OnDelete(IEntity entity)
{
XTrace.WriteLine("删除实体 " + entity.GetType().Name);
return base.OnDelete(entity);
}
public static void Test()
{
EntityModules.Global.Add<TestModule>();
var user = new UserX
{
Name = "Stone",
RoleID = 1
};
user.Save();
user.Name = "大石头";
user.Update();
user.Delete();
}
}
模块TestModule继承自抽象基类EntityModule,它实现了IEntityModule接口的基本功能。
EntityModules.Global.Add<TestModule>(); 用于把该模块注册成为全局处理模块
也可以注册到具体单个实体类里面,比如 UserX.Meta.Modules.Add<TestModule>();
Init方法用于判断指定实体类是否需要执行过滤模块,只有它返回true,后面的接口方法才会被调用。
OnValid等同于实体类的Valid,新增或修改实体对象时会调用,通过isNew参数区分。因为绝大多数业务逻辑的新增和修改都有关系,所以把它们做到一块。
OnDelete就是删除拦截啦。如果想做假删除,就是在这里把删除标记字段改为true,然后entity.Update保存,接着返回false让外部不要继续执行Delete
在XCode内部,有三个最常用的接口实现:UserModule、TimeModule、IPModule
它们的功能如下:
1,新增时CreateUserID使用当前登录用户(通过IManageProvider接口获取),新增修改时UpdateUserID使用当前登录用户
2,新增时CreateTime使用当前时间,新增修改时UpdateTime使用当前时间
3,新增时CreateIP使用当前访问地址(通过WebHelper.UserHost),新增修改时UpdateIP使用当前访问地址
所以,这六个字段赫赫有名,就写在NX001软件设计标准里面。
一般在需要用到的实体类静态构造函数里面注册使用。
static Shard()
{
// 过滤器 UserModule、TimeModule、IPModule
Meta.Modules.Add<UserModule>();
Meta.Modules.Add<TimeModule>();
Meta.Modules.Add<IPModule>();
}
实际使用中,只要一个团队遵循统一的数据库设计规范,就一定可以抽象出来许多IEntityModule实现!