• 实战框架ABP


    abp及实战框架概述

      接触abp也快一年了,有过大半年的abp项目开发经验,目前项目中所用的abp框架版本为0.10.3,最新的abp框架已经到了1.4,并且支持了asp.net core。关于abp框架有哪些特性、有什么好处我这里就不讲了。如果你对abp不太了解请先去 Abp官网 了解或者参考我的学习之路里面的链接。在这系列的文章里面我会把我在实战中的经验、碰到的坑分享出来。希望跟大家一起学习讨论。

      学习之路  

         一年前在博客园里面看到了阳光铭睿 的 http://www.cnblogs.com/mienreal/p/4528470.html 一系列文章使我对abp框架产生了兴趣。从此开始了abp框架的探索之路。后来在找资料的过程中发现 tkb至简 的博客写的也非常不错,他也翻译了官网的英文文档 http://www.cnblogs.com/farb/category/762156.html ,要入门的话看下这一系列的文章非常好。如果想研究源码可以参考下 http://www.cnblogs.com/1zhk/category/798531.html 这一系列的文章。

       Abp在github上的源码地址为:https://github.com/aspnetboilerplate。

      框架概述

      这个框架版本主要用的技术有 mvc5.0、web api、EF 6.1 。

       一、整体框架概述

    Topeveyr.Core:主要存放业务实体以及仓储接口。

    Application文件夹:这里面有两个应用服务层,当时是想做读写分离的,一个读一个写。但是底层的数据访问层没有实现读写分离。(全完实现读写分离还没找到解决方案)

    Topevery.EntityFramework.Oracle:主要存放实体映射文件、仓储实现类。

    Topevery.Web:web界面。

    Topevery.WebApi:api接口。

    Topevery.Infrastructure:框架中跟业务无关的公共类。

    Topevery.WF.Framework:流程业务相关项目。

    Topevery.Abp:封装了abp类的公共类。

    TimeServices:定时服务类库。

    Dapper:一款轻量级orm框架。主要是为了支持EF操作Oracled包而加进来的。如果是其他数据库可以忽略该项目。为了更好的统一,以后应该全部换成存储过程。

    Zero文件夹:这里面的三个项目分别对应abp的应用服务层、核心层、数据访问层。这个项目主要用来操作一些基础信息表以及公共模块。比如,用户、角色、权限、部门等。

     二、整体框架设计

          整体框架设计里面,我觉得“模块”的比较重要,这里就讲一讲我对模块的理解。每个单独类库或者应用程序即是一个模块。当需要用到Ioc容器、abp启动配置或者是在应用程序启动的时候做一些设置就需要用到abp里面的模块。模块类可以被依赖。模块类在应用程序启动的时候被执行,并且按依赖的关系进行执行。即没有被依赖的模块最后执行。模块有四个方法,PreInitialize()、Initialize()、PostInitialize()、Shutdown()。前三个方法是在应用程序启动的时候运行的,最后一个方法是在应用程序关闭的时候运行的。模块方法的执行顺序是先执行完所有模块的PreInitialize(),再执行所有模块的Initialize(),最后执行所有模块的PostInitialize()。

      整体框架模块的依赖设计图如下:

                     

       

       三、框架详细设计

          本框架大概思路是根据abp的示例代码而来。我只是参照原来的框架做了一些扩展。相同的框架设计就不讲了。讲一讲不同之处。在本框架里面的Zero项目跟官方Abp.Zero不同。Abp.Zero里面基本上都是提供抽象类,要具体实例化必须得在相应的业务类库里面继承才能用。本框架里的Zero项目直接提供对外的服务接口。Topevery.Zero是应用服务接口。Topevery.Zero.Core存放实体仓储接口。Topevery.Zero.EntityFramework.Oracel是数据访问抽象层,该类库里面有继承了AbpDbContext的抽象类。由于本框架用的是Oracle,目前还没有找到EF操作自增长类型的解决方案。所以目前插入数据的时候解决思路是先获取序列再插入数据。

        获取序列的话有两种解决方案。一种是在仓储的基类里面添加公共方法,这种方案的优势可以很好的集成依赖注入,并且可以做到事务控制。但这种方案的劣势是所有的实体类都必须有对应的仓储基类。另外一种方案是新增一个数据访问DbContext。这个方案的优势在于可以在应用服务的基类里面添加一个获取序列的公共方法。劣势是序列的获取和其他数据的操作不能一起做事务控制。

         我在框架里面采用的是第二种方案。整体思路是在 Topevery.Zero.EntityFramework.Oracle 项目中添加 IDbContextHelper 接口,该接口有两个获取序列的方法。在Topevery.EntityFramework.Oracle 项目中添加 DbContextHelper,该类继承 IDbContextHelper 接口,并且有个 DbContext 的变量,用来访问数据库。为啥要这样设计?因为解耦。所有 Zero 里面的的项目都不需要直接引用具体的DbContextHelper而只要引用接口即可,具体的接口实现是在运行的时候注入。具体代码如下:

     1  public interface IDbContextHelper
     2     {
     3         /// <summary>
     4         /// 获取序列值
     5         /// </summary>
     6         /// <typeparam name="T"></typeparam>
     7         /// <param name="sequenceName"></param>
     8         /// <returns></returns>
     9         T GetSequenceValueByName<T>(string sequenceName) where T : struct;
    10 
    11         /// <summary>
    12         /// 获取序列值(默认int)
    13         /// </summary>
    14         /// <param name="sequenceName"></param>
    15         /// <returns></returns>
    16         int GetSequenceValueByName(string sequenceName);
    17     }
    View Code
     1 public class DbContextHelper:IDbContextHelper,ITransientDependency
     2     {
     3         /// <summary>
     4         /// 数据访问类
     5         /// </summary>
     6         private volatile DbContext _dbContext ;
     7 
     8         /// <summary>
     9         /// 锁帮助对象
    10         /// </summary>
    11         private readonly object _lockObject = new object();
    12 
    13         /// <summary>
    14         /// 
    15         /// </summary>
    16         private  DbContext TopeveryDbContext
    17         {
    18             get
    19             {
    20                 if (_dbContext == null)
    21                 {
    22                     lock (_lockObject)
    23                     {
    24                         if (_dbContext == null)
    25                             _dbContext = IocManager.Instance.Resolve<TopeveryDbContext>();
    26                     }
    27                 }
    28                 return _dbContext;
    29             }
    30         }
    31 
    32         /// <summary>
    33         /// 得到序列的字符串
    34         /// </summary>
    35         /// <param name="sequenceName"></param>
    36         /// <returns></returns>
    37         private string GetSequenceSqlByName(string sequenceName)
    38         {
    39             return "select " + sequenceName + ".nextval from dual";
    40         }
    41 
    42         /// <summary>
    43         /// 获取序列值
    44         /// </summary>
    45         /// <typeparam name="T"></typeparam>
    46         /// <param name="sequenceName"></param>
    47         /// <returns></returns>
    48         public T GetSequenceValueByName<T>(string sequenceName) where T : struct
    49         {
    50             string sql = GetSequenceSqlByName(sequenceName);
    51             return TopeveryDbContext.Database.SqlQuery<T>(sql).First();
    52         }
    53 
    54 
    55         /// <summary>
    56         /// 获取序列值(默认int)
    57         /// </summary>
    58         /// <param name="sequenceName"></param>
    59         /// <returns></returns>
    60         public int GetSequenceValueByName(string sequenceName) 
    61         {
    62             return GetSequenceValueByName<int>(sequenceName);
    63         }
    64     }
    View Code

       今天就讲这么多了。

       源码地址:https://github.com/yuanbeier/JMGF.git

    ABP理论基础篇

    发表一些关于ABP基础理论性的文章
    摘要: "返回总目录" 本篇目录 "介绍" "ASP.NET MVC" "ASP.NET WEB API" "ASP.NET Core" 【以后补上】 "客户端类库" "内部原理" 介绍 CSRF【Cross Site Request Forgery】 跨站请求伪造是一种攻击类型,一般指的是一个恶意的网站、阅读全文
    posted @ 2016-09-17 23:28 tkbSimplest 阅读(4209) | 评论 (1) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "Clock" "时区" "绑定器和转换器" 介绍 虽然有些应用针对的是一个特定的时区,但是也有一些应用针对多个不同的时区。为了满足这些需求,ABP为datetime操作提供了通用的基础设施。 Clock Clock 是用于处理 DateTime 类型的主要操作类阅读全文
    posted @ 2016-09-13 13:10 tkbSimplest 阅读(2947) | 评论 (0) 编辑
     
    摘要: "返回总目录" Hangfire是一个综合的后台工作管理者。你可以将Hangfire集成到ABP中,这样就可以不使用默认的后台工作管理者了。但你仍然可以为Hangfire使用 相同的后台工作API 。这样,你的代码就独立于Hangfire了,但是,如果你喜欢的话,也可以直接使用 Hangfire的A阅读全文
    posted @ 2016-03-11 15:06 tkbSimplest 阅读(2970) | 评论 (0) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "后台工作" "后台工作者" "让你的应用程序一直运行" 介绍 ABP提供了后台工作和后台工作者,它们会在应用程序的 后台线程 中执行一些任务。 后台工作 后台工作以队列和持续的方式在后台给一些即将被执行的任务排队。你可能因为某些原因需要后台工作,比如: 执行 长阅读全文
    posted @ 2016-03-11 08:33 tkbSimplest 阅读(7610) | 评论 (5) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "安装" "建立连接" "内置功能" "你自己的SignaR代码" 介绍 "Abp.Web.SignalR" 使得在基于ABP的应用程序中使用 SignalR 相当容易。查看 "SignalR文档" 获取更多关于SignalR的详细信息。 安装 服务端 将 "Ab阅读全文
    posted @ 2016-03-09 23:47 tkbSimplest 阅读(4423) | 评论 (5) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "订阅通知" "发布通知" "用户通知管理者" "实时通知" "通知存储" "通知定义" 介绍 通知(Notification)用于告知用户系统中的特定事件。ABP提供了基于 实时 通知基础设施的发布订阅模型(pub/sub)。 发送模型 给用户发送通知有两种方式阅读全文
    posted @ 2016-03-06 13:11 tkbSimplest 阅读(5992) | 评论 (11) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "安装" "安装Nuget包" "配置" "测试" 介绍 从官方网站上可以看到:“启用了Swagger API,就可以获得交互式文档,生成和发现客户端SDK”。 安装 将 "Swagger" 集成到基于ABP的应用中是很容易的事情。 安装Nuget包 将 "Swa阅读全文
    posted @ 2016-03-03 23:02 tkbSimplest 阅读(4762) | 评论 (4) 编辑
     
    摘要: "返回总目录" 如果你的应用中使用了 OWIN ,那么需要在主项目(一般来说是指Web项目)中添加 "Abp.Owin" 的nuget包,然后像下面那样在OWIN的 Startup 文件中调用 UseAbp() 扩展方法:阅读全文
    posted @ 2016-03-03 18:57 tkbSimplest 阅读(3696) | 评论 (0) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "安装" "创建控制器" "例子" "样例项目" <a name='intro' </a 介绍 OData 在 "其官网" 的定义是: 允许以一种 简单且标准 的方式创建和使用 可查询的、可互操作的 RESTful APIs。在ABP中也可以...阅读全文
    posted @ 2016-01-23 19:06 tkbSimplest 阅读(2641) | 评论 (10) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "AbpController基类" "本地化" "异常处理" "响应结果的包装" "审计日志" "授权" "工作单元" "其他" <a name='intro' </a 介绍 ABP通过Abp.Web.Mvc nuget包集...阅读全文
    posted @ 2016-01-21 22:51 tkbSimplest 阅读(3245) | 评论 (0) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "AbpWebViewPage基类" <a name='intro' </a 介绍 ABP通过 Abp.Web.Mvc Nuget包集成了MVC视图。因此你可以像常规那样创建MVC视图。 <a name='base' </a AbpWebViewPag...阅读全文
    posted @ 2016-01-21 10:25 tkbSimplest 阅读(2020) | 评论 (0) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "AbpApiController基类" "本地化" "审计日志" "授权" "工作单元" "其他" <a name='intro' </a 介绍 ABP通过 Abp.Web.Api Nuget包集成了 ASP.NET Web AP...阅读全文
    posted @ 2016-01-20 22:22 tkbSimplest 阅读(3649) | 评论 (2) 编辑
     
    摘要: "返回总目录" 本篇目录 "构建动态Web API控制器" "ForAll 方法" "重写ForAll 方法" "Http动词" "动态Javascript代理" "Ajax参数" "单一服务脚本" "Angular支持" "Durandal支持" "返回结果封装" 【2016/3/28 更新】 "阅读全文
    posted @ 2016-01-06 14:50 tkbSimplest 阅读(6900) | 评论 (7) 编辑
     
    摘要: "返回总目录" 本篇目录 "Ajax" "Notification" "Message" "UI block和busy" "事件总线" "Logging" "其他工具功能" 说在前面的话 不知不觉,我们送走了2015,同时迎来了2016。我相信,每一个人,都会在过去的一年有所失,但我更相信,我们所得阅读全文
    posted @ 2016-01-03 17:44 tkbSimplest 阅读(9377) | 评论 (3) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "功能类型" "定义功能" "检查功能" "功能管理者" "版本说明" <a name='intro' </a 介绍 大多数的 Saas (多租户)应用都有不同 功能 的 版本 (包)。因此,他们可以给租户(客户)提供不同的 价格和功能选项 。...阅读全文
    posted @ 2016-01-02 22:26 tkbSimplest 阅读(3411) | 评论 (7) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "定义权限" "检查权限" "使用AbpAuthorize特性" "使用IPermissionChecker" "Razor视图" "客户端(Javascript)" "权限管理者" 介绍 几乎所有的企业应用都在不同程度使用了授权。授权的目的在于检查是否允许用户在阅读全文
    posted @ 2016-01-02 11:32 tkbSimplest 阅读(7584) | 评论 (7) 编辑
     
    摘要: "返回总目录" 本篇目录 "应用语言" "本地化资源" "获取本地化文本" "扩展本地化资源" "最佳实践" 应用语言 一个应用至少有一种UI语言,许多应用不止有一种语言。ABP为应用提供了一个灵活的本地化系统。 第一件事情就是声明支持哪些语言。这个是在模块的 PreInitialize 方法中完成阅读全文
    posted @ 2016-01-01 13:30 tkbSimplest 阅读(4442) | 评论 (3) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "开启错误处理" "非Ajax请求" "展示异常信息" "UserFriendlyException" "Error模型" "Ajax请求" "异常事件" <a name='intro' </a 介绍 在一个web应用中,异常通常是在...阅读全文
    posted @ 2015-12-31 21:47 tkbSimplest 阅读(7206) | 评论 (6) 编辑
     
    摘要: "返回总目录" 本篇目录 "创建菜单" "注册导航提供者" "展示菜单" 每一个web应用在页面之间都有一些要导航的菜单。ABP提供了公用的基础设施来创建菜单并将菜单展示给用户。 <a name='create' </a 创建菜单 一个应用可能由不同的模块组成,每个模块可能有它自己的菜...阅读全文
    posted @ 2015-12-30 21:39 tkbSimplest 阅读(2580) | 评论 (2) 编辑
     
    摘要: "返回总目录" 本篇目录 "验证介绍" "使用数据注解" "自定义验证" "标准化" <a name='intro' </a 验证介绍 首先应该验证应用的输入。用户或者其它应用都可以向该应用发送输入。在一个web应用中,验证通常要实现两次:在客户端和服务器端。客户端的验证大多数情况下...阅读全文
    posted @ 2015-12-29 22:35 tkbSimplest 阅读(3624) | 评论 (7) 编辑
     
    摘要: "返回总目录" 本篇目录 "为何需要DTO" "领域层抽象" "数据隐藏" "序列化和懒加载问题" "DTO惯例和验证" "DTO和实体的自动映射" "使用特性和扩展方法进行映射" "帮助接口" DTO用于 应用层 和 展现层 间的数据传输。展现层调用具有DTO参数的 ...阅读全文
    posted @ 2015-12-29 12:19 tkbSimplest 阅读(6408) | 评论 (6) 编辑
     
    摘要: "返回总目录" 本篇目录 "IApplicationService接口" "ApplicationService类" "工作单元" "数据库连接和事务管理" "自动保存更改" "更多" "应用服务的生命周期" 应用服务用于将领域逻辑暴露给展现层。展现层调用具有DTO参数的应用服务,使用领域对象来执行阅读全文
    posted @ 2015-12-28 18:05 tkbSimplest 阅读(3042) | 评论 (10) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "预定义过滤器" "关闭过滤器" "开启过滤器" "设置过滤器参数" "定义自定义过滤器" "其他ORM" <a name='intro' </a 介绍 软删除 模式通常用于不会真正从数据库删除一个实体而是仅仅将它标记为"已删除的"。这样,...阅读全文
    posted @ 2015-12-27 11:32 tkbSimplest 阅读(4362) | 评论 (2) 编辑
     
    摘要: "返回总目录" 本篇目录 "事件总线" "定义事件" "触发事件" "处理事件" "句柄注册" "取消注册" 在C 中,我们可以在一个类中定义自己的事件,而其他的类可以注册该事件,当某些事情发生时,可以通知到该类。这对于桌面应用或者独立的windows服务来说是非常有用的。但对于一个web应用来说是阅读全文
    posted @ 2015-12-26 20:56 tkbSimplest 阅读(6252) | 评论 (7) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "创建内嵌文件" "暴露内嵌文件" "使用内嵌文件" <a name='intro' </a 介绍 在一个web应用中,有供客户端使用的javascript,css,xml等文件。它们一般是作为分离的文件被添加到web项目中并发布。有时,我们需要将...阅读全文
    posted @ 2015-12-25 23:08 tkbSimplest 阅读(1843) | 评论 (2) 编辑
     
    摘要: "返回总目录" 本篇目录 "公共连接和事务管理方法" "ABP中的连接和事务管理" "仓储类" "应用服务" "工作单元" "工作单元详解" "关闭工作单元" "非事务的工作单元" "工作单元方法调用其它" "工作单元作用域" "自动保存" "IRepository.GetAll()方法" "Uni阅读全文
    posted @ 2015-12-24 21:49 tkbSimplest 阅读(6432) | 评论 (14) 编辑
     
    摘要: "返回总目录" 本篇目录 "Nuget包" "配置" "实体映射" "仓储" "仓储基类" "实现仓储" "自定义仓储方法" "阅读其他" ABP可以使用任何ORM框架工作,并且已经内置了 NHibernate 集成。这篇文章会解释如何在ABP中使用NHibernate。阅读本文的前提是假设你已经熟阅读全文
    posted @ 2015-12-24 00:02 tkbSimplest 阅读(2013) | 评论 (2) 编辑
     
    摘要: "返回总目录" 本篇目录 "Nuget包" "创建DbContext" "仓储" "仓储基类" "实现仓储" "自定义仓储方法" "阅读其他" ABP可以使用任何ORM框架工作,并且已经内置了 EntityFramework 集成。这篇文章会解释如何在ABP中使用Entit...阅读全文
    posted @ 2015-12-23 17:22 tkbSimplest 阅读(4080) | 评论 (1) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "IDomainService接口和DomainService类" "样例" "创建一个接口" "服务实现" "调用应用服务" "一些讨论" "何不只使用应用服务" "如何强制使用领域服务" <a name='intro' </...阅读全文
    posted @ 2015-12-23 00:16 tkbSimplest 阅读(6573) | 评论 (9) 编辑
     
    摘要: "返回总目录" 本篇目录 "IRepository接口" "查询" "插入" "更新" "删除" "其他" "关于异步方法" "仓储实现" "管理数据库连接" "仓储的生命周期" "仓储最佳实践" Martin Fowler对仓储的定义 位于领域层和数据映...阅读全文
    posted @ 2015-12-22 12:46 tkbSimplest 阅读(6510) | 评论 (7) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "配置" "通过特性开启/关闭" "注意" "我项目中的例子" <a name="intro" </a 介绍 维基百科说: “审计跟踪(也叫审计日志)是与安全相关的按照时间顺序的记录,记录集或者记录源,它们提供了活动序列的文档证据,这些活动序...阅读全文
    posted @ 2015-12-21 13:45 tkbSimplest 阅读(4735) | 评论 (2) 编辑
     
    摘要: "返回总目录" 本篇目录 "实体类" "惯例接口" "审计" "软删除" "激活/未激活" "IEntity接口" 实体是DDD(领域驱动设计)的核心概念之一。Eirc Evans是这样描述的实体的:“它根本上不是通过属性定义的,而是通过一系列连续性和标识定义的”。因此,实...阅读全文
    posted @ 2015-12-20 22:57 tkbSimplest 阅读(5813) | 评论 (5) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "定义设置" "获取设置值" "更改设置" "关于缓存" 介绍 每个应用程序都需要存储一些设置信息,然后在应用程序中的某个地方使用这些设置。ABP提供了健壮的基础设施来存储或检索服务端和客户端的 应用程序,租户,用户 级别的可用设置。 一个设置一般是存储在数据库(阅读全文
    posted @ 2015-12-18 14:19 tkbSimplest 阅读(5040) | 评论 (6) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "ICacheManager" "ICache" "ITypedCache" "配置" <a name='intro' </a 介绍 ABP提供了缓存的抽象,它内部使用了这个缓存抽象。虽然默认的实现使用了MemoryCache,但是也可以为其他的...阅读全文
    posted @ 2015-12-17 23:57 tkbSimplest 阅读(5714) | 评论 (0) 编辑
     
    摘要: "返回总目录" 本篇目录 "服务端" "获取Logger" "基类中的Logger" "配置" "客户端" <a name='server' </a 服务端 ABP使用的是Castle Windsor的 "日志记录设备" 。它可以和不同的日志类库一起工作,比如 Log4Net...阅读全文
    posted @ 2015-12-17 15:22 tkbSimplest 阅读(4129) | 评论 (5) 编辑
     
    摘要: "返回总目录" 本篇目录 "介绍" "注入Session" "使用Session属性" <a name='intro' </a 介绍 当应用程序要求用户登录时,那么应用程序也需要知道当前用户正在执行的操作。虽然ASP.NET本身在展现层提供了Session对象,但ABP也提供了在任何需...阅读全文
    posted @ 2015-12-17 12:03 tkbSimplest 阅读(5583) | 评论 (0) 编辑
     
    摘要: "返回总目录" 本篇目录 "什么是依赖注入" "传统方式产生的问题" "解决办法" "依赖注入框架" "ABP中的依赖注入基础设施" "注册" "解析" "其他" "ASP.NET MVC和ASP.NET Web API集成" "最后提示" 什么是依赖注入 维基百科说:“依赖注入是一种软件设计模式,阅读全文
    posted @ 2015-12-16 22:19 tkbSimplest 阅读(10516) | 评论 (12) 编辑
     
    摘要: "返回总目录" "查看更详细信息以及下载源代码请查看原文档" ABP v0.9.2.0 | 【更新日期:2016/6/6 11:21:28 】 解决方案转换成xproj/project.json格式。 添加了Appveyor持续集成。 创建了EntityCache基类,可以轻松缓存实体了。 添加了可阅读全文
    posted @ 2015-12-15 23:53 tkbSimplest 阅读(3748) | 评论 (0) 编辑
     
    摘要: "返回总目录" 本篇目录 "框架" "测试基" ABP已经发布在Nuget上,这里是所有包的列表。 <a name='framework' </a 框架 "Abp" Abp系统的核心包。所有其他的包都依赖这个包。 "Abp.Web" 提供了MVC和Web API都使用的一些通用类和资源 ...阅读全文
    posted @ 2015-12-14 23:56 tkbSimplest 阅读(2452) | 评论 (0) 编辑
     
    摘要: "返回总目录" 本篇目录 "什么是多租户" "ABP中的多租户" <a name='what' </a 什么是多租户 维基百科:“软件 多租户 是指一种软件架构,在这种软件架构中,软件的 一个实例 运行在服务器上并且为多个租户服务”。一个租户是一组共享该软件实例特定权限的用户。有了多租户...阅读全文
    posted @ 2015-12-13 20:39 tkbSimplest 阅读(10271) | 评论 (7) 编辑
     
    摘要: "返回总目录" 本篇目录 "配置ABP" "配置模块" "为模块创建配置" 为了在应用启动时配置ABP和模块,ABP提供了一个基础设施。 <a name='abp' </a 配置ABP 配置ABP是在模块的 PreInitialize 事件中完成的。下面的代码摘自Github上的Task...阅读全文
    posted @ 2015-12-12 21:53 tkbSimplest 阅读(6634) | 评论 (5) 编辑
     
    摘要: "返回总目录" 本篇目录 "模块介绍" "生命周期事件" "模块依赖" "自定义模块方法" <a name='intro' </a 模块介绍 ABP提供了构建模块并将这些模块组合起来创建应用的基础设施。一个模块可以依赖另一个模块。一般来说,一个程序集可以认为是一个模块。一个模块是由一...阅读全文
    posted @ 2015-12-12 10:29 tkbSimplest 阅读(8258) | 评论 (6) 编辑
     
    摘要: "返回总目录" 自从写这个系列博客之后,发现很多园友还是希望有个直接运行的demo,其实在github上就有官方的demo,我直接把这demo的链接放到这里吧,另外,我分析,这些找不到demo的同学,很可能是不怎么用github,可能的原因就是英文不好。所以还是希望程序员多看看英文文档,一开始看...阅读全文
    posted @ 2015-12-11 13:16 tkbSimplest 阅读(10950) | 评论 (10) 编辑
     
    摘要: "返回总目录" 为了和2016年春节赛跑,完成该系列博客,我牺牲了今天中午的时间来完成该系列的第一篇————开篇介绍。开篇介绍嘛,读过大学教材的同学都知道,这玩意总是那么无聊,跟考试没关系,干脆直接跳过,呵呵,多么美好的大学时光啊!不过,现在想想,开篇介绍确实不怎么重要,它只是告诉我们今后我要开始讲阅读全文
    posted @ 2015-12-10 18:31 tkbSimplest 阅读(15066) | 评论 (7) 编辑
     
    摘要: 目前,我已经完成了Module Zero的翻译,请查看我的 "《Module Zero学习目录》" 。 到现在为止,使用ABP框架开发正式项目已经3个月有余了,期间翻阅了大量文档资料,包括ABP官网的文档,以及 @阳光铭睿 的系列教程。 但是我今天想回过头来,照着ABP官网的英文文档,加上我这几个月阅读全文
    posted @ 2015-12-10 12:25 tkbSimplest 阅读(76835) | 评论 (54) 编辑

    BP

     
    摘要: ABP 中异常处理的思路是很清晰的。一共五种类型的异常类。 AbpInitializationException用于封装ABP初始化过程中出现的异常,只要抛出AbpInitializationException异常就可以,无须做额外处理。这类异常往往是需要维护人员介入分析的。 其他四个异常都在Abp阅读全文
    posted @ 2016-05-29 10:44 ZHK的博客 阅读(1309) | 评论 (0) 编辑
     
    摘要: 通过AD作为用户认证的数据源。整个管理用户认证逻辑就在LdapAuthenticationSource类中实现。 LdapSettingProvider:定义LDAP的setting和提供DefautValue。主要提供配置访问AD数据库的账号信息。 LdapSettings/ILdapSettin阅读全文
    posted @ 2016-05-19 20:42 ZHK的博客 阅读(769) | 评论 (2) 编辑
     
    摘要: AbpZeroDbContext:配置ABP.Zero中定义的entity的Dbset EntityFrameworkModelBuilderExtensions:给PrimitivePropertyConfiguration添加了扩展方法用于创建Index。 AbpZeroDbModelBuild阅读全文
    posted @ 2016-05-14 15:55 ZHK的博客 阅读(782) | 评论 (4) 编辑
     
    摘要: ABP Zero模块中需要配置的地方主要集中在三块:配置静态的role,配置外部认证源,以及配置本地化语言和资源。 UserManagementConfig/IUserManagementConfig:定义了一个配置项,用于配置外部认证源。默认情况下,ABP Zero使用AbpUser表作为身份认证阅读全文
    posted @ 2016-05-06 13:33 ZHK的博客 阅读(643) | 评论 (1) 编辑
     
    摘要: ABP Zero模块扩展了ABP基础框架中的本地化功能,实现了通过数据库管理本地化的功能。其通过数据库保存本地化语言及其资源。 ApplicationLanguage:代表本地化语言的实体类。一种语言就是一个ApplicationLanguage实例。 ApplicationLanguageProv阅读全文
    posted @ 2016-05-05 12:49 ZHK的博客 阅读(893) | 评论 (2) 编辑
     
    摘要: ABP Zero模块通过自定义实现Asp.Net Identity完成身份认证功能, 对Asp.Net Identity做了较大幅度的扩展。同时重写了ABP核心模块中的permission功能,以实现授权。注意:ABP仅仅使用了Asp.Net Identity的身份认证功能,但没有使用Asp.Net阅读全文
    posted @ 2016-05-04 14:10 ZHK的博客 阅读(1650) | 评论 (2) 编辑
     
    摘要: AuditLog: 继承自Entity<long>的实体类。封装AuditLog的信息。 AuditingStore: 实现了IAuditingStore接口,实现了将AuditLog的信息保存到数据库的功能。其通过IRepository<AuditLog, long>实例完成对数据库的操作。 Ba阅读全文
    posted @ 2016-05-02 10:40 ZHK的博客 阅读(776) | 评论 (1) 编辑
     
    摘要: ABP的Zero模块以数据库为数据源实现了ABP框架中的tenant management (multi-tenancy), role management, user management, session, authorization (permission management), setti阅读全文
    posted @ 2016-05-01 17:45 ZHK的博客 阅读(1340) | 评论 (1) 编辑
     
    摘要: ABP对HangFire的集成主要是通过实现IBackgroundJobManager接口的HangfireBackgroundJobManager类完成的。 HangfireBackgroundJobManager:实现了接口IBackgroundJobManager中的方法EnqueueAsyn阅读全文
    posted @ 2016-04-27 14:50 ZHK的博客 阅读(880) | 评论 (1) 编辑
     
    摘要: 如果对OData不熟悉的话可参考OData的初步认识一文以获取OData的一些初步知识。 API.Odata 模块唯一用处就是提供了一个泛型版本的ODataController,实现了Controller代码的常用。 AbpODataEntityController<TEntity, TPrimar阅读全文
    posted @ 2016-04-26 19:56 ZHK的博客 阅读(379) | 评论 (1) 编辑
     
    摘要: ABP提供Script Proxy WebApi为所有的Dynamic WebApi生成访问这些WebApi的JQuery代理,AngularJs代理以及TypeScriptor代理。这些个代理就是javascript脚本,通过这些代理可以简单的访问Dynamic webApi。 如下实例演示一个最阅读全文
    posted @ 2016-04-25 19:47 ZHK的博客 阅读(816) | 评论 (1) 编辑
     
    摘要: 这里的内容和ABP 动态webapi没有关系。除了动态webapi,ABP必然是支持使用传统的webApi。ABP.Web.Api模块中实现了一些同意的基础功能,以方便我们创建和使用asp.net webApi。 AbpApiController:这是一个抽象基类,继承自ApiController,阅读全文
    posted @ 2016-04-24 08:19 ZHK的博客 阅读(1092) | 评论 (3) 编辑
     
    摘要: 动态WebAPI应该算是ABP中最Magic的功能之一了吧。开发人员无须定义继承自ApiController的类,只须重用Application Service中的类就可以对外提供WebAPI的功能,这应该算是对DRY的最佳诠释了. 如下图所示,一行代码就为所有实现了IApplicationServ阅读全文
    posted @ 2016-04-23 07:58 ZHK的博客 阅读(4390) | 评论 (4) 编辑
     
    摘要: ABP.Web.Mvc模块主要完成两个任务: 第一,通过自定义的AbpController抽象基类封装ABP核心模块中的功能,以便利的方式提供给我们创建controller使用。 第二,一些常见的基础功能的实现。 AbpController:这是一个抽象基类,继承自MVC Controller,是A阅读全文
    posted @ 2016-04-20 14:05 ZHK的博客 阅读(703) | 评论 (2) 编辑
     
    摘要: ABP.Web模块并不复杂,主要完成ABP系统的初始化和一些基础功能的实现。 AbpWebApplication : 继承自ASP.Net的HttpApplication类,主要完成下面三件事一,在Application_Start完成AbpBootstrapper的初始化。整个ABP系统的初始化就阅读全文
    posted @ 2016-04-18 21:16 ZHK的博客 阅读(766) | 评论 (1) 编辑
     
    摘要: Realtime Realtime是ABP底层模块提供的功能,用于管理在线用户。它是使用SignalR实现给在线用户发送通知的功能的前提 IOnlineClient/OnlineClient: 封装在线用户的信息 OnlineClientManager/IOnlineClientManager: 用阅读全文
    posted @ 2016-04-16 08:25 ZHK的博客 阅读(1005) | 评论 (2) 编辑
     
    摘要: 这个模块封装了Automapper,使其更易于使用。 下图描述了改模块涉及的所有类之间的关系。 AutoMapAttribute,AutoMapFromAttribute和AutoMapToAttribute:这三个attribute用于标注一个类到另外一个类的map方向。 AutoMapperHe阅读全文
    posted @ 2016-04-14 22:29 ZHK的博客 阅读(1106) | 评论 (1) 编辑
     
    摘要: ABP 通过StackExchange.Redis类库来操作Redis数据库。 AbpRedisCacheModule:完成ABP.RedisCache模块的初始化(完成常规的依赖注入) AbpRedisCacheConfig:定义了connectionStringKey和databaseIdApp阅读全文
    posted @ 2016-04-13 22:24 ZHK的博客 阅读(1005) | 评论 (1) 编辑
     
    摘要: 这个Module通过建立一个MongoDbRepositoryBase<TEntity> 基类,封装了对MongoDb数据库的操作。 这个module通过引用MongoDB.Driver,MongoDB.Bson,MongoDB.Driver.Core,MongoDB.Driver.Legacy类库阅读全文
    posted @ 2016-04-12 21:07 ZHK的博客 阅读(720) | 评论 (7) 编辑
     
    摘要: 这个模块简单,且无实际作用。一般实际项目中都有用数据库做持久化,用了数据库就无法用这个MemoryDB 模块了。原因在于ABP限制了UnitOfWork的类型只能有一个(前文以作介绍),一般用了数据库的必然要注入efUnitOfWork. 而注入了efUnitOfWork就不能在注入MemoryDb阅读全文
    posted @ 2016-04-11 20:26 ZHK的博客 阅读(520) | 评论 (1) 编辑
     
    摘要: IRepository:接口定义了Repository常见的方法 AbpRepositoryBase:实现了IRepository接口的常见方法 EfRepositoryBase:实现了AbpRepositoryBase中定义的抽象方法:GetAll,Insert,Delete,Update。在实际阅读全文
    posted @ 2016-04-10 13:32 ZHK的博客 阅读(1496) | 评论 (2) 编辑
     
    摘要: 本文是ABP核心项目源码分析的最后一篇,介绍一些前面遗漏的功能 AbpSession AbpSession: 目前这个和CLR的Session没有什么直接的联系。当然可以自定义的去实现IAbpSession使之与CLR的Session关联 IAbpSession:定义如下图中的四个属性。 NullA阅读全文
    posted @ 2016-04-09 16:19 ZHK的博客 阅读(923) | 评论 (3) 编辑
     
    摘要: IEventData/EventData: 封装了EventData信息,触发event的源对象和时间 IEventBus/EventBus: 定义和实现了了一系列注册,注销和触发事件处理函数的方法。EventBus定义了一个Dictionary容器来存放事件和处理该事件的对象(其实不是对象而是Fa阅读全文
    posted @ 2016-04-08 21:58 ZHK的博客 阅读(1066) | 评论 (11) 编辑
     
    摘要: NotificationDefinition: 用于封装Notification Definnition 的信息。注意和Notification 的区别,如果把Notification看成是具体的消息内容,NotificationDefinition则是对这个消息自身的定义(可理解为消息的类型)。 阅读全文
    posted @ 2016-04-07 22:23 ZHK的博客 阅读(720) | 评论 (3) 编辑
     
    摘要: Permission:用于定义一个Permission,一个permission可以包含多个子Permission. PermissionDictionary:继承自Dictionary<string, Permission>类,很明显是一个用于存储permission对象的字典。 IPermiss阅读全文
    posted @ 2016-04-06 21:27 ZHK的博客 阅读(1111) | 评论 (2) 编辑
     
    摘要: MenuDefinition:封装了导航栏上的主菜单的属性。 MenuItemDefinition:封装了主菜单的子菜单的属性。子菜单可以引用其他子菜单构成一个菜单树 UserMenu/UserMenuItem:封装了用于显示给用户的菜单/以及子菜单集合。 ABP通过MenuDefinition/M阅读全文
    posted @ 2016-04-05 21:08 ZHK的博客 阅读(646) | 评论 (1) 编辑
     
    摘要: Feature是什么?Feature就是对function的分类方法,其与function的关系就比如Role和User的关系一样。 ABP中Feature具有以下属性: 其中最重要的属性是name,用以表示feature的Identity,一个feature一个name. 一个Feature可以有阅读全文
    posted @ 2016-04-04 14:29 ZHK的博客 阅读(924) | 评论 (10) 编辑
     
    摘要: IApplicationService : 空接口,起标识作用。所有实现了IApplicationService 的类都会被自动注入到容器中。同时所有IApplicationService对象都会被注入一些拦截器(例如:auditing, UnitOfWork等)以实现AOP AbpServiceB阅读全文
    posted @ 2016-04-01 16:51 ZHK的博客 阅读(859) | 评论 (1) 编辑
     
    摘要: 审计跟踪(也叫审计日志)是与安全相关的按照时间顺序的记录,它们提供了活动序列的文档证据,这些活动序列可以在任何时间影响一个特定的操作。 AuditInfo:定义如下图中需要被Audit的信息。 AuditedAttribute: 用于标识一个方法或一个类的所有方法都需要启用Auditing功能。 D阅读全文
    posted @ 2016-04-01 15:57 ZHK的博客 阅读(1179) | 评论 (2) 编辑
     
    摘要: 以下图中描述的接口和类都在Abp项目的Runtime/Validation, UI/Inputs目录下的。在当前版本的ABP(0.83)中这些接口和类并没有实际使用到。阅读代码时可以忽略,无需浪费时间去寻找其是如何被ABP使用的(本文的目的)。 这些接口和类最终都是通过IInputType被Feat阅读全文
    posted @ 2016-03-31 19:17 ZHK的博客 阅读(659) | 评论 (0) 编辑
     
    摘要: 对传给Application service对象中的方法的DTO参数,ABP都会在方法真正执行前自动完成validation(根据标注到DTO对象中的validate规则)。 ABP是如何做到的? 思路无外乎通过Castle的拦截器实现AOP。本文主要分析ABP是如何设计。 Ivalidate: 空阅读全文
    posted @ 2016-03-30 22:08 ZHK的博客 阅读(1257) | 评论 (2) 编辑
     
    摘要: IDTO:空接口,用于标注Dto对象。 ComboboxItemDto:用于combobox/list中Item的DTO NameValueDto<T>/NameValueDto:用于name value键值对的DTO, name为string类型, value为泛型或string类型。 Entit阅读全文
    posted @ 2016-03-29 22:05 ZHK的博客 阅读(2166) | 评论 (2) 编辑
     
    摘要: 类名 扩展的类型 方法名 参数 作用 XmlNodeExtensions XmlNode GetAttributeValueOrNull attributeName Gets an attribute's value from an Xml node. JsonExtensions object T阅读全文
    posted @ 2016-03-28 22:08 ZHK的博客 阅读(958) | 评论 (1) 编辑
     
    摘要: IEntity<TPrimaryKey>: 封装了PrimaryKey:Id,这是一个泛型类型 IEntity: 封装了PrimaryKey:Id,这是一个int类型 Entity<TPrimaryKey> :支持主键是泛型类型的Entity Entity:支持主键是int类型的Entity IHa阅读全文
    posted @ 2016-03-28 16:07 ZHK的博客 阅读(1665) | 评论 (3) 编辑
     
    摘要: ABP中有两种cache的实现方式:MemroyCache 和 RedisCache. 如下图,两者都继承至ICache接口(准确说是CacheBase抽象类)。ABP核心模块封装了MemroyCache 来实现ABP中的默认缓存功能。 Abp.RedisCache这个模块封装RedisCache来阅读全文
    posted @ 2016-03-28 12:18 ZHK的博客 阅读(2135) | 评论 (3) 编辑
     
    摘要: 本文逐个分析ABP中涉及到locaization的接口和类,以及相互之间的关系。本地化主要涉及两个方面:一个是语言(Language)的管理,这部分相对简单。另一个是语言对应得本地化资源(Localization)的管理,这部分稍显复杂。 LanguageInfo:用于封装language的基本信息阅读全文
    posted @ 2016-03-25 20:07 ZHK的博客 阅读(1299) | 评论 (4) 编辑
     
    摘要: Timing这个简单实用的功能主要用于以统一的方式表示时间。因为ABP中有大量的module,还支持自定义module,所以将时间统一表示为local时间(默认)或utc时间是必要的。 IClockProvider:提供获取当前时间和标准化时间的接口。 UtcClockProvider:实现了以UT阅读全文
    posted @ 2016-03-24 20:22 ZHK的博客 阅读(789) | 评论 (4) 编辑
     
    摘要: ABP以AOP的方式实现UnitOfWork功能。通过UnitOfWorkRegistrar将UnitOfWorkInterceptor在某个类被注册到IOCContainner的时候,一并添加到该类在容器中对应的ComponentModel的Interceptors集合中。总结一句话就是,UOW的阅读全文
    posted @ 2016-03-23 17:48 ZHK的博客 阅读(2174) | 评论 (13) 编辑
     
    摘要: 文主要说明ABP中后台工作者模块(BackgroundWorker)的实现方式,和后台工作模块(BackgroundJob)。ABP通过BackgroundWorkerManager来管理BackgroundJobManager,然后通过BackgroundJobManager来管理Backgrou阅读全文
    posted @ 2016-03-22 19:10 ZHK的博客 阅读(2359) | 评论 (7) 编辑
     
    摘要: ABP使用Castle日志记录工具,并且可以使用不同的日志类库,比如:Log4Net, NLog, Serilog... 等等。对于所有的日志类库,Castle提供了一个通用的接口来实现,我们可以很方便的处理各种特殊的日志库,而且当业务需要的时候,很容易替换日志组件。 Logger功能模块涉及到的接阅读全文
    posted @ 2016-03-21 19:44 ZHK的博客 阅读(1233) | 评论 (5) 编辑
     
    摘要: 本文主要说明Setting的实现以及Mail这个功能模块如何使用Setting. 首先区分一下ABP中的Setting和Configuration。 Setting一般用于需要通过外部配置文件(或数据库)设置的简单类型数据(一般就是字符串),比如SMTP HOST. Configuration一般只阅读全文
    posted @ 2016-03-20 21:12 ZHK的博客 阅读(2199) | 评论 (7) 编辑
     
    摘要: ABP的依赖注入的实现有一个本质两个途径:1.本质上是依赖于Castle这个老牌依赖注入的框架。2.一种实现途径是通过实现IConventionalDependencyRegistrar的实例定义注入的约定(规则),然后通过IocManager来读取这个规则完成依赖注入。3另一种实现途径是直接Ioc阅读全文
    posted @ 2016-03-19 20:30 ZHK的博客 阅读(2773) | 评论 (7) 编辑
     
    摘要: ABP在初始化阶段做了哪些操作,前面的四篇文章大致描述了一下。 为个更清楚的描述其脉络,做了张流程图以辅助说明。其中每一步都涉及很多细节,难以在一张图中全部表现出来。每一步的细节(会涉及到较多接口,类,调用关系,步骤流程什么的)会在后面的文章中通过其他图和文字详细描述。其实如果仔细分析Abp原代码的阅读全文
    posted @ 2016-03-18 16:37 ZHK的博客 阅读(2032) | 评论 (6) 编辑
     
    摘要: 核心模块的配置 Configuration是ABP中设计比较巧妙的地方。其通过AbpStartupConfiguration,Castle的依赖注入,Dictionary对象和扩展方法很巧妙的实现了配置中心化。配置中心化是一个支持模块开发的框架必备功能。 ABP中核心功能模块中的一些功能的运行时的行阅读全文
    posted @ 2016-03-17 15:00 ZHK的博客 阅读(2238) | 评论 (6) 编辑
     
    摘要: Abp是一种基于模块化设计的思想构建的。开发人员可以将自定义的功能以模块(module)的形式集成到ABP中。具体的功能都可以设计成一个单独的Module。Abp底层框架提供便捷的方法集成每个Module.下图是所有Abp自带的module.AbpModule是所有Module的基类,其已经拥有了I阅读全文
    posted @ 2016-03-16 15:42 ZHK的博客 阅读(4318) | 评论 (3) 编辑
     
    摘要: 一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法。执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成了。 ABP开始的地方就是HttpApplication的构造函数。 如下图一,Abp定义了一个继承阅读全文
    posted @ 2016-03-15 17:22 ZHK的博客 阅读(5114) | 评论 (8) 编辑
     
    摘要: ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序。 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module).其中13个依赖于Abp这个核心包。另外两个包(FluentMigration,Web.Resou阅读全文
    posted @ 2016-03-12 10:36 ZHK的博客 阅读(15310) | 评论 (18) 
  • 相关阅读:
    jenkins本地运行方法
    项目开发规则
    finally与catch的执行
    idea中实现热部署
    vue的错误的ERR!代码ELIFECYCLE
    spring注解的使用
    mysql中with as相关用法8.0之后支持
    stream流遇到的问题
    git解决冲突,在乌龟工具中一定要点击提交
    jquery知识 内部 外部插入元素
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/7805807.html
Copyright © 2020-2023  润新知