ABP(现代ASP.NET样板开发框架)系列之10、ABP领域层——实体
基于DDD的现代ASP.NET开发框架--ABP系列之10、ABP领域层——实体
ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。
ABP的官方网站:http://www.aspnetboilerplate.com
ABP在Github上的开源项目:https://github.com/aspnetboilerplate
本文由深圳-Carl提供翻译
实体是DDD(领域驱动设计)的核心概念之一。Eric Evans是这样描述的“很多对象不是通过它们的属性定义的,而是通过一连串的连续性事件和标识定义的”(引用领域驱动设计一书)。
译者注:对象不是通过它们的属性来下根本性的定义,而应该是通过它的线性连续性和标识性定义的。。所以,实体是具有唯一标识的ID且存储在数据库中。实体通常被映射成数据库中的一个表。
实体类(Entity classes)
在ABP中,实体继承自Entity类,请看下面示例:
public class Person : Entity
{
public virtual string Name { get; set; } public virtual DateTime CreationTime { get; set; } public Task()
{
CreationTime = DateTime.Now;
}
}
Person 类被定义为一个实体。它具有两个属性,它的父类中有Id属性。Id是该实体的主键。所以,Id是所有继承自Entity类的实体的主键(所有实体的主键都是Id字段)。
Id(主键)数据类型可以被更改。默认是int(int32)类型。如果你想给Id定义其它类型,你应该像下面示例一样来声明Id的类型。
public class Person : Entity<long>
{
public virtual string Name { get; set; } public virtual DateTime CreationTime { get; set; } public Task()
{
CreationTime = DateTime.Now;
}
}
你可以设置为string,Guid或者其它数据类型。
实体类重写了 equality (==) 操作符用来判断两个实体对象是否相等(两个实体的Id是否相等)。还定义了一个IsTransient()方法来检测实体是否有Id属性。
接口约定
在很多应用程序中,很多实体具有像CreationTime的属性(数据库表也有该字段)用来指示该实体是什么时候被创建的。APB提供了一些有用的接口来实现这些类似的功能。也就是说,为这些实现了这些接口的实体,提供了一个通用的编码方式(通俗的说只要实现指定的接口就能实现指定的功能)。
(1)审计(Auditing)
实体类实现 IHasCreationTime 接口就可以具有CreationTime的属性。当该实体被插入到数据库时, ABP会自动设置该属性的值为当前时间。
public interface IHasCreationTime
{
DateTime CreationTime { get; set; }
}
Person类可以被重写像下面示例一样实现IHasCreationTime 接口:
public class Person : Entity<long>, IHasCreationTime
{
public virtual string Name { get; set; } public virtual DateTime CreationTime { get; set; } public Task()
{
CreationTime = DateTime.Now;
}
}
ICreationAudited 扩展自 IHasCreationTime 并且该接口具有属性 CreatorUserId :
public interface ICreationAudited : IHasCreationTime
{
long? CreatorUserId { get; set; }
}
当保存一个新的实体时,ABP会自动设置CreatorUserId 的属性值为当前用户的Id
你可以轻松的实现ICreationAudited接口,通过派生自实体类 CreationAuditedEntity (因为该类已经实现了ICreationAudited接口,我们可以直接继承CreationAuditedEntity 类就实现了上述功能)。它有一个实现不同ID数据类型的泛型版本(默认是int),可以为ID(Entity类中的ID)赋予不同的数据类型。
下面是一个为实现类似修改功能的接口
public interface IModificationAudited
{
DateTime? LastModificationTime { get; set; }
long? LastModifierUserId { get; set; }
}
当更新一个实体时,APB会自动设置这些属性的值。你只需要在你的实体类里面实现这些属性。
如果你想实现所有的审计属性,你可以直接扩展 IAudited 接口;示例如下:
public interface IAudited : ICreationAudited, IModificationAudited
{ }
作为一个快速开发方式,你可以直接派生自AuditedEntity 类,不需要再去实现IAudited接口(AuditedEntity 类已经实现了该功能,直接继承该类就可以实现上述功能),AuditedEntity 类有一个实现不同ID数据类型的泛型版本(默认是int),可以为ID(Entity类中的ID)赋予不同的数据类型。
(2)软删除(Soft delete)
软删除是一个通用的模式被用来标记一个已经被删除的实体,而不是实际从数据库中删除记录。例如:你可能不想从数据库中硬删除一条用户记录,因为它被许多其它的表所关联。为了实现软删除的目的我们可以实现该接口 ISoftDelete:
public interface ISoftDelete{
bool IsDeleted { get; set; }
}
ABP实现了开箱即用的软删除模式。当一个实现了软删除的实体正在被被删除,ABP会察觉到这个动作,并且阻止其删除,设置IsDeleted 属性值为true并且更新数据库中的实体。也就是说,被软删除的记录不可以从数据库中检索出,ABP会为我们自动过滤软删除的记录。(例如:Select查询,这里指通过ABP查询,不是通过数据库中的查询分析器查询。)
如果你用了软删除,你有可能也想实现这个功能,就是记录谁删除了这个实体。要实现该功能你可以实现IDeletionAudited 接口,请看下面示例:
public interface IDeletionAudited : ISoftDelete
{
long? DeleterUserId { get; set; }
DateTime? DeletionTime { get; set; }
}
正如你所看到的IDeletionAudited 扩展自 ISoftDelete接口。当一个实体被删除的时候ABP会自动的为这些属性设置值。
如果你想为实体类扩展所有的审计接口(例如:创建(creation),修改(modification)和删除(deletion)),你可以直接实现IFullAudited接口,因为该接口已经继承了这些接口,请看下面示例:
public interface IFullAudited : IAudited, IDeletionAudited
{ }
作为一个快捷方式,你可以直接从FullAuditedEntity 类派生你的实体类,因为该类已经实现了IFullAudited接口。
注意:所有的审计接口和类都有一个泛型模板为了导航定义属性到你的User 实体(例如:ICreationAudited<TUser>和FullAuditedEntity<TPrimaryKey, TUser>),这里的TUser指的进行创建,修改和删除的用户的实体类的类型,详细请看源代码(Abp.Domain.Entities.Auditing空间下的FullAuditedEntity<TPrimaryKey, TUser>类),TprimaryKey 只的是Entity基类Id类型,默认是int。
(3)激活状态/闲置状态(Active/Passive)
有些实体需要被标记为激活状态或者闲置状态。那么你可以为实体采取active/passive状态的行动。基于这个原因而创建的实体,你可以扩展IPassivable 接口来实现该功能。该接口定义了IsActive 的属性。
如果你首次创建的实体被标记为激活状态,你可以在构造函数设置IsActive属性值为true。
这是不同于软删除(IsDeleted)。如果实体被软删除,它不能从数据库中被检索到(ABP已经过滤了软删除记录)。但是对于激活状态/闲置状态的实体,你完全取决于你怎样去获取这些被标记了的实体。
IEntity接口
事实上Entity 实现了IEntity 接口(和Entity<TPrimaryKey> 实现了 IEntity<TPrimaryKey>接口)。如果你不想从Entity 类派生,你能直接的实现这些接口。其他实体类也可以实现相应的接口。但是不建议你用这种方式。除非你有一个很好的理由不从Entity 类派生。
希望更多国内的架构师能关注到ABP这个项目,也许这其中有能帮助到您的地方,也许有您的参与,这个项目可以发展得更好。
欢迎加ABP架构设计交流QQ群:134710707

ABP(现代ASP.NET样板开发框架)系列之10、ABP领域层——实体的更多相关文章
- ABP(现代ASP.NET样板开发框架)系列之18、ABP应用层——权限验证
点这里进入ABP系列文章总目录 ABP(现代ASP.NET样板开发框架)系列之18.ABP应用层——权限验证 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目 ...
- ABP(现代ASP.NET样板开发框架)系列之20、ABP展现层——动态生成WebApi
点这里进入ABP系列文章总目录 ABP(现代ASP.NET样板开发框架)系列之20.ABP展现层——动态生成WebApi ABP是“ASP.NET Boilerplate Project (ASP.N ...
- ABP(现代ASP.NET样板开发框架)系列之3、ABP分层架构
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之3.ABP分层架构 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...
- ABP(现代ASP.NET样板开发框架)系列之4、ABP模块系统
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之4.ABP模块系统 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...
- ABP(现代ASP.NET样板开发框架)系列之5、ABP启动配置
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之5.ABP启动配置 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...
- ABP(现代ASP.NET样板开发框架)系列之6、ABP依赖注入
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之6.ABP依赖注入 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...
- ABP(现代ASP.NET样板开发框架)系列之7、ABP Session管理
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之7.ABP Session管理 ABP是“ASP.NET Boilerplate Project (ASP.NET ...
- ABP(现代ASP.NET样板开发框架)系列之8、ABP日志管理
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之8.ABP日志管理 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...
- ABP(现代ASP.NET样板开发框架)系列之9、ABP设置管理
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之9.ABP设置管理 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...
随机推荐
- PHP-生成缩略图和添加水印图-学习笔记
1.开始 在网站上传图片过程,经常用到缩略图功能.这里我自己写了一个图片处理的Image类,能生成缩略图,并且可以添加水印图. 2.如何生成缩略图 生成缩略图,关键的是如何计算缩放比率. 这里,我根据 ...
- jQuery的61种选择器
The Write Less , Do More ! jQuery选择器 1. #id : 根据给定的ID匹配一个元素 <p id="myId">这是第一个p标签< ...
- 微信小程序体验(2):驴妈妈景区门票即买即游
驴妈妈因为出色的运营能力,被腾讯选为首批小程序内测单位.驴妈妈的技术开发团队在很短的时间内完成了开发任务,并积极参与到张小龙团队的内测问题反馈.驴妈妈认为,移动互联网时代,微信是巨大的流量入口,也是旅 ...
- Yii1.1的验证规则
在Yii1.1的数据验证是由CValidator完成,在CValidator中提供了各种基本的验证规则 <?php public static $builtInValidators=array( ...
- Canvas讲解
1.Canvas是什么? 简单地说canvas是画布,可以进行画任何的线.图形.填充等一系列的操作,而且操作的画图就是js, 提供简单的二维矢量绘图. 2.步骤: <canvas id=&quo ...
- 安卓GreenDao框架一些进阶用法整理
大致分为以下几个方面: 一些查询指令整理 使用SQL语句进行特殊查询 检测表字段是否存在 数据库升级 数据库表字段赋初始值 一.查询指令整理 1.链式执行的指令 return mDaoSession. ...
- 两个变量交换的四种方法(Java)
对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) class TestEV //创建一个类 { public static ...
- keepalive的不足,如何处理
MySQL(或者其它服务)的keepalived高可用监控脚本 开发脚本需求:我们知道,keepalive是基于虚拟ip的存活来判断是否抢占master的机制的,但是如果我们做了MySQL的keepa ...
- VisualStudio 2015 开启IIS Express可以调试X64项目
现在项目开发时总有时需要在X64下开发,这样我们就需要IIS Express中调试.不要总是放在IIS中,在Attach这样好慢. 如果不设置直接调试X64的程序,我们有可能会受到以下类似的错误 ...
- Dubbo 备注
Dubbo是阿里开源的一款服务治理中间件,主要包含如下节点: Provider: 暴露服务的服务提供方. Consumer: 调用远程服务的服务消费方. Registry: 服务注册与发现的注册中心. ...