此处的Domain主要指Abp类库根目录下Domain文件夹。顾名思义该目录下是用来存放与领域实体,领域逻辑执行,存储,领域服务相关的内容。

  1.Entities

   (1)为整个Abp框架后期开发的所有实体Model提供接口及基础实现,总的来讲为实现某种规范的接口都拥有两个,一个是主键数据类型为泛型的实现,另一个则是继承该泛型接口并为泛型提供一个默认的数据类型,例如IEntity<TPrimaryKey>的属性Id就为TPrimaryKey类型,另一个接口IEntity只是接单的继承上述接口并指定一个int型public interface IEntity : IEntity<int>,最基本的模型接口IEntity<TPrimaryKey>提供了一个实现类public abstract class Entity<TPrimaryKey>,提供了对象比较功能,bool Equals(object obj)和int GetHashCode()方法。Entities提供了一个IMayHaveTenant接口只有一个可空的TenantId属性,用于确定实体是否属于应用级别的(值为空)或者租户级别以及哪个租户,在后面的EF的DynamicFilter也会用到。同时提供了一个IMustHaveTenant接口含有一个不可空的TenantId属性,指明实体对象属于哪个租户所有,IPassivable接口包含一个IsActive的布尔类型的属性,用以指明实体对象是否激活状态。ISoftDelete是为软删除设计模式设计的布尔类型的IsDeleted属性表明实体记录是否已被删除,对于EF搜索可用对象集合十分有帮助,ISoftDelete接口拥有一个扩展方法bool IsNullOrDeleted(this ISoftDelete entity)可以方便表明对象是否属于已删除状态。

   (2)Entities为框架额外提供了一个审计模型接口包括一些基类实现,用以在实体对象中保存相关信息如:创建人,删除人,更新人,更新时间用以保存到持久化设备中。所有的设计类型都有泛型类型(主要用于指定主键类型)和默认类型(指明主键的类型)。同时还有一个两个泛型参数的版本,用以设置一个外键方便跳转到相应实体。

public abstract class CreationAuditedEntity<TPrimaryKey, TUser> : CreationAuditedEntity<TPrimaryKey>, ICreationAudited<TUser>
where TUser : IEntity<long>
{
/// <summary>
/// Reference to the creator user of this entity.
/// </summary>
[ForeignKey("CreatorUserId")]
public virtual TUser CreatorUser { get; set; }
}
  • CreationAuditedEntity<TPrimaryKey>,如果模型实例仅需记录创建者ID和创建时间,那么继承该抽象类就可以了,此时也无需再继承Entity<TPrimaryKey>抽象类就已经是一个符合领域规范的实体了。
  • AuditedEntity<TPrimaryKey>,继承于第一个泛型类,同时添加了可空的修改人Id和修改时间
  • FullAuditedEntity<TPrimaryKey>,为了方便实体记录中添加创建人,修改人,是否已处于删除状态,还有删除人,删除时间,提供了此类包含上述所有需要记录的信息。

  2.Policies

   只是提供了一个IPolicy接口,无任何实现。

  3.Repositories

   (1)IRepository空接口用以表明实例是一个Repository。

   (2)IRepository<TEntity, TPrimaryKey>包含一个真正的Repository所拥有的CRUD方法,第一个泛型表示将要操作的实体类型(必须继承自IEntity<TPrimaryKey>接口),第二个泛型表示TEntity中主键的类型。主要分为五大块,分别是1.Select/Get/Query(用以搜索返回记录)2.Insert 3.Update 4.Delete 5.Aggregate(计算所有记录数),所有的方法都有同步及异步。

   (3)AbpRepositoryBase<TEntity, TPrimaryKey>,关于上述接口,框架提供了一个默认实现,该实现是一个抽象类,定义了数个抽象方法用以在具体所使用的ORM框架来决定真正逻辑,public abstract IQueryable<TEntity> GetAll();就是这样一个需要在后面实现的抽象类,所有其他的查找方法都是依赖此方法来完成自己的逻辑的,所以如果用EF来做ORM的话只需新建一个EFRepository并实现GetAll()抽象方法就ok了,1.public abstract TEntity Update(TEntity entity);2.public abstract void Delete(TEntity entity);同样如此。

  4.Services

   该块是系统的领域驱动服务,拥有一个空的IDomainService接口,同时拥有一个实现DomainService,这是一个抽象类,并继承AbpServiceBase,在AbpServiceBase类中已经存在ISettingManager,IUnitOfWorkManager,IActiveUnitOfWork,ILocalizationManager,ILogger(默认是一个空实现但是可以通过属性注入获得有意义的Logger,如果容器中有的话),还有一个本地方的方法string L(string name, CultureInfo culture, params object[] args)。

  5.UOW

   系统中所有事务逻辑都是保存于此的(系统默认是IApplicationService和IRepository方法执行时会生成事务环境并保存在静态私有字典字段中,通过线程槽中得到GUID去唯一匹配)。另外也可以为所以将会存入依赖容器的类型的方法上应用UnitOfWorkAttribute来保证在事务中被执行,同时该特性有一个IsDisabled来关闭默认事务。

   (1)在系统的启动阶段,会注册相关的类型到依赖容器中,如果是IApplicationService和IRepository或者类型或者方法上应用了UnitOfWorkAttribute依赖容器就会为该类添加一个UnitOfWorkInterceptor,确保方法在事务环境中被执行,该拦截器的void Intercept(IInvocation invocation)方法执行时会首先通过IUnitOfWorkManager的Current属性获取保存到线程槽中的IUnitOfWork(实际上是IUnitOfWork的GUID键值),如果不为空说明其已经在一个事务上下文中了,下面直接执行真正的逻辑就行了,如果为空的话会尝试获取应用在方法上的UnitOfWorkAttribute特性,如果没有的话会new一个新的(默认单元工作类上没有),利用此特性创建UnitOfWorkOptions,利用得到的options作为参数调用IUnitOfWorkManager的Begin方法,Begin方法会返回一个完成句柄,该句柄同时也是Disposable的,如果真正的逻辑执行ok,在最后会调用完成句柄的Complete()完成保存,同时该句柄也会被Dispose掉,通过Begin方法保存到线程数据槽中的IUnitOfWork也会被释放掉。(真正的执行逻辑是可以分异步同步的,都是支持的)

   (2)UnitOfWorkBase具有一些事件像Completed,Failed,Disposed都会在事务的相应阶段被处罚,需要额外处理一些东西的话可以监控这些事件,关于动态过滤的所有参数也UnitOfWorkBase中设置添加,在UnitOfWorkBase的继承类中会使用到控制在数据库的记录集的筛选。SaveChanges方法执行真正的保存逻辑也需要根据不同的ORM而有所变化的。所以当前是抽象方法。

   (3)CallContextCurrentUnitOfWorkProvider,在每次生成新的IUnitOfWork的时候我们需要存放这些对象以方便在函数调用堆栈中的方法的获得,所以提供了这样一个类,实际上IUnitOfWorkManager的Current属性就是调用该类的同名属性来获取的,当创建新的IUnitOfWork的时候,也通过此类的Current属性来保存。当获取当前环境的IUnitOfWork的时候会先从线程数据槽中得到当前执行线程的单元工作的GUID,CallContext.LogicalGetData(ContextKey),如果不存在就返回null,如果存在就从该类的ConcurrentDictionary<string, IUnitOfWork> UnitOfWorkDictionary私有静态只读属性中获取相应的IUnitOfWork,如果不存在就返回null,同时清空数据槽中的GUID,如果存在就获取IUnitOfWork再猜判断是否已经Dispose掉了,没有被Dispose就返回该IUnitOfWork,否则清理数据返回null。而设置保存一个新建的IUnitOfWork则是跟获取的方法执行流程相反。

ABP框架详解(三)Domain的更多相关文章

  1. ABP框架详解(七)Caching

    在ABP框架中存在一个缓存机制,使用ICache的继承类来存储最终需要缓存的数据,可以吧ICache看成一个字典对象,使用Key作为真实数据的具有唯一性的表示.使用上与字典对象完全相同,Get方法传递 ...

  2. ABP框架详解(二)AbpKernelModule

    AbpKernelModule类是Abp框架自己的Module,它也跟所有其他的Module一样继承自AbpModule,重写PreInitialize,Initialize,PostInitiali ...

  3. ABP框架详解(一)ABPBootstrapper

    在ABP框架的AbpBootstrapper主要用于框架的基本配置的注册和初始化,在Web应用启动阶段实例化一个AbpBootstrapper并调用Initialize方法初始化,该类主要包含两个公有 ...

  4. ABP框架详解(八)动态ApiController的生成和访问机制

    在ABP框架中提供了一套动态生成ApiController的机制(依然支持原生ApiController的使用方式),虽然说是动态生成ApiController但是实际上并没有真正在启动程序的时候生成 ...

  5. ABP框架详解(五)Navigation

    ABP框架中的Navigation功能用于管理业务系统中所有可用的菜单导航控件,通常在业务系统的首页会有一个全局性的导航菜单,JD商城,天猫,猪八戒网莫不如是.所以为方便起见,Navigation功能 ...

  6. ABP框架详解(四)Feature

    ABP框架中存在一个Feature的特性,功能和设计思路非常类似于框架中的Authorization功能,都是来控制用户是否能够继续操作某项功能,不同点在于Authorization默认是应用在IAp ...

  7. ABP框架详解(六)Aspects

    这种AOP式的设计非常类似于Asp.net MVC和WebApi中过滤器(Filter)机制,感觉没有太多可讲述的,只能谈谈设计思路. 框架中AspectAttribute特性用于设置到需要被拦截的T ...

  8. Shiro 安全框架详解二(概念+权限案例实现)

    Shiro 安全框架详解二 总结内容 一.登录认证 二.Shiro 授权 1. 概念 2. 授权流程图 三.基于 ini 的授权认证案例实现 1. 实现原理图 2. 实现代码 2.1 添加 maven ...

  9. jQuery Validate验证框架详解

    转自:http://www.cnblogs.com/linjiqin/p/3431835.html jQuery校验官网地址:http://bassistance.de/jquery-plugins/ ...

随机推荐

  1. Ueditor 编译发布后无法使用上传图片、附件等功能

    Ueditor 发布后上传到服务器会出现无法使用上传功能,在本地源代码模式下上传功能正常,这是因为在网站发布期间把 net/Uploader.cs 给编译了,发布后的代码不包含Uploader.cs故 ...

  2. SQL Server Management Studio 2012 设置脚本默认保存路径

    特别说明,本文是从这里 修改SQL Server Management Studio默认设置提高开发效率. "抄过来的",为方便个人记忆才写此文(非常感谢这哥们儿的分享.) 原文地 ...

  3. 准备开发一款开源NES模拟器

    前几天无意见看到一些NES的开发资料,勾起了小时候暑假的无数美好回忆,做为一名码农,萌发了自己写一款模拟器的想法.一来可以加深自己对整个系统/游戏的理解,一来可以实现小时候的梦想:),希望可以坚持下来 ...

  4. 炼数成金(dataguru)IT技能修炼

    2016我定的目标就是要走出舒适区,进入学习区!为了少走弯路,节约学习的成本和时间,我选择了dataguru.看到心仪的课程毫不犹豫的就报了名. 分享了炼数成金邀请码,使用邀请码报名课程可以减免50% ...

  5. Python list列表的排序

    当我们从数据库中获取一写数据后,一般对于列表的排序是经常会遇到的问题,今天总结一下python对于列表list排序的常用方法: 第一种:内建函数sort() 这个应该是我们使用最多的也是最简单的排序函 ...

  6. MSMQ(Microsoft Message Queue)

    http://www.cnblogs.com/sk-net/archive/2011/11/25/2232341.html 利用 MSMQ(Microsoft Message Queue),应用程序开 ...

  7. 使用spring的特殊bean完成配置

    1.分散配置 beans.xml配置如下: 使用占位符变量代替bean装配文件中的硬编码配置.占位符采用${variable}形式. 说明:当通过context:property-placeholde ...

  8. sqlite3 根据实体自动生成建表语句

      public class BuildSqlTool { public static string GetCreateTableSql(object t) { //CREATE TABLE &quo ...

  9. easyui datagird 列宽自适应

    代码如下: onLoadSuccess: function (data) { var rows = data.rows; //得到行数据 var columnMaxCharacter = new Ar ...

  10. 原子操作--ARM架构

    说明:内核版本号为3.10.101 一.ARM架构中的原子操作实现 在原子操作(一)中我们已经提到,各个架构组织为“复仇者”联盟,统一了基本的原子变量操作,这里我们就拿atomic_dec(v)来看看 ...