此处的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则是跟获取的方法执行流程相反。

转载于:https://www.cnblogs.com/Azula/p/4991838.html

ABP框架详解(三)Domain相关推荐

  1. ABP框架详解(一)ABPBootstrapper

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

  2. ABP框架详解(二)AbpKernelModule

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

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

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

  4. ABP框架详解(六)Aspects

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

  5. jQuery Validate验证框架详解

    2019独角兽企业重金招聘Python工程师标准>>> 一.导入js库 <script type="text/javascript" src="& ...

  6. [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解

    深入浅出 Cocoa 之 Core Data(1)- 框架详解 罗朝辉(http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 Core data 是 Cocoa 中处 ...

  7. WebDriver自动化测试框架详解

    webDriver自动化测试框架详解 一. 简介 WebDriver API相对于Selenium Remote Control API来说,虽然同样是控制浏览器,但它的编程接口更加简洁 WebDri ...

  8. Android 动画框架详解,第 1 部分

    2019独角兽企业重金招聘Python工程师标准>>> Android 平台提供了一套完整的动画框架,使得开发者可以用它来开发各种动画效果,本文将向读者阐述 Android 的动画框 ...

  9. iOS开发之Accounts框架详解

    2019独角兽企业重金招聘Python工程师标准>>> iOS开发之Accounts框架详解 Accounts框架是iOS原生提供的一套账户管理框架,其支持Facebook,新浪微博 ...

最新文章

  1. php imagecopy 用法,php使用imagecopymerge()函数创建半透明水印
  2. 参与组织社区活动总结
  3. 在python中使用csv库以字典格式读写csv文件
  4. mongoclient php扩展,lnmp安装mongo扩展后,在实例化mongoClient()时出错
  5. 与、或、短路或、自增、自减、的执行过程
  6. Java 使用 POI 对 Excel文件 进行读写操作
  7. 【SCIR AAAI2021】数据增强没效果?试试用Cluster-to-Cluster生成更多样化的新数据吧...
  8. pads 2007的概述
  9. mysql和oracle的索引类型
  10. Java实现简单的QQ登录界面
  11. iso硬盘安装 凤凰os_凤凰系统安装教程-凤凰虚拟机2.0(Phoenix OS)下载v3.6.1可重启版-西西软件下载...
  12. Last-Modified和Etag
  13. 关于一名零基础蒟蒻ACM变强的路子
  14. mt9638和t972哪个好
  15. [Discuz!模板] 听雨轩风格[GBK][utf8][一键安装 DIY][20110918更新]
  16. 仙剑4 linux,仙剑奇侠传98柔情版 for Linux——SDLPAL打包
  17. 【论文阅读笔记 + 代码解读】(2018 AAAI)ST-GCN
  18. 《为什么精英都是时间控》读书总结
  19. jupyter没有输出直接下一行
  20. 15条建议,把技术成果写成一篇高质量学术论文

热门文章

  1. 华为云服务器自己维护吗,云服务器要维护吗
  2. y7000 intel nvidia 双显卡安装Ubuntu16.04
  3. 手写体识别(数据挖掘入门与实践-实验11)
  4. Leetcode-88:合并两个有序数组
  5. [数据结构] 二叉树基础
  6. Linux线程——线程同步
  7. java 2wei shuzu_JavaScript 2维数组(JavaScript 2 dimension array)
  8. ed是什么梗_花泽香菜不笑了什么梗怎么回事?花泽香菜为什么是宅男女神?
  9. 数据库中的DML,DCL,DDL分别是那些操作?
  10. 【经典问题】maximum subset sum of vectors