基于DDDLite的权限管理OpenAuth.net 1.0版正式发布

      距离上一篇OpenAuth.net的文章已经有5个多月了,在这段时间里项目得到了很多朋友的认可,开源中国上面的Star数接近300,于是坚定了我做下去的信心。最近稍微清闲点,正式推出1.0版,并在阿里云上部署了一个在线演示(文章结尾处给出在线演示链接)。相比刚开始时的版本,现在整个架构已经稳定,系统功能性,代码可读性维护性都有质的飞跃。

        本文主要介绍系统结构及未来一段时间的开发计划。

项目简介

        本项目采用经典DDD架构(用沃恩.弗农大神的话,其实这是DDD-Lite)思想进行开发的一套符合国情的基于用户和角色的RBAC系统,系统的产生原因及与众不同的地方可以参考:领域驱动设计实战—基于DDDLite的权限管理OpenAuth.net,这里就不过多介绍。项目地址:

https://git.oschina.net/yubaolee/OpenAuth.Net

演示地址在文章结尾处给出:)

当前项目功能:

  1. 模块权限  实现模块的自定义及权限分配;

  2. 菜单权限 实现菜单的自定义及权限分配;

  3. 资源权限  实现资源的自定义及权限分配,主要是为了给第三方应用提供服务;

  4. 实现用户分配角色,也可以直接给用户分配模块/菜单;

  5. 基于ASP.NET Identity登录;

  6. 实现一个简单的进出库管理的例子,在例子中使用admin,test登录或直接以“开发者账号”登录,看到的结果是不同的;

项目这一年里都发生了什么?

准确的说应该是5个月来发生了什么,因为项目正式发布刚刚5个多月的时间。最高兴的应该是入选了:开源中国2015 年度新增开源软件排名 TOP 100  在新入选的5977个项目中位列第69。也算为C#那可怜的开源份额做点贡献了!

 

系统架构

首先到底什么是经典DDD架构?

DDD:领域驱动设计,以领域业务为核心的设计。什么?这是屁话,很多书上都介绍过?

那我就从代码的角度来解释就是:丫就是你的XXXBLL模块不要引用诸如XXXDAL/XXXHELPER等模块并且能够实现系统的业务逻辑,基本就是了。如下图:

基于上面的结构创建本项目。所有的依赖关系在界面OpenAuth.Mvc项目中由AutoFac进行IOC控制,如下图:

OpenAuth.Domain 系统领域层,当前领域层主要有下面三部分组成:

  • 领域对象:系统核心对象;

  • 领域接口:当前主要是数据库访问的仓储接口,具体的实现在OpenAuth.Repository中实现;

  • 领域服务:系统的多对象交互业务处理。由于当前的业务复杂度比较低,业务主要是以领域服务的形式出现。如项目中的“进出库管理服务”:

  1. using System;  

  2. using System.Linq;  

  3. using System.Linq.Expressions;  

  4. using OpenAuth.Domain.Interface;  

  5.   

  6. namespace OpenAuth.Domain.Service  

  7. {  

  8.     /// <summary>  

  9.     /// 领域服务  

  10.     /// <para>进出库管理服务</para>  

  11.     /// </summary>  

  12.     public class StockManagerService  

  13.     {  

  14.         private IStockRepository _repository;  

  15.         private IOrgRepository _orgRepository;  

  16.         private AuthoriseService _authoriseService;  

  17.   

  18.         public StockManagerService(IStockRepository repository,  

  19.             IOrgRepository orgRepository, AuthoriseService service)  

  20.         {  

  21.             _repository = repository;  

  22.             _orgRepository = orgRepository;  

  23.             _authoriseService = service;  

  24.         }  

  25.   

  26.         /// <summary>  

  27.         /// 根据部门ID得到进出库信息  

  28.         /// </summary>  

  29.         public dynamic Load(string username, int orgId, int pageindex, int pagesize)  

  30.         {  

  31.   

  32.             _authoriseService.GetUserAccessed(username);  

  33.             if (_authoriseService.Orgs.Count == 0) //用户没有任何可见机构  

  34.             {  

  35.                 return new  

  36.                 {  

  37.                     total = 0,  

  38.                     pageCurrent = pageindex  

  39.                 };  

  40.             }  

  41.   

  42.             var orgIds = _authoriseService.Orgs.Select(u => u.Id).ToArray();  //用户可访问的机构ID  

  43.   

  44.             var orgs = _orgRepository.GetSubWithOwn(orgId)   //点击的节点与用户可访问的机构合并  

  45.                 .Where(u => orgIds.Contains(u.Id))  

  46.                 .Select(u => u.Id).ToArray();  

  47.   

  48.             var keys = _authoriseService.Resources.Select(r => r.Key);    //用户可访问的资源的KEY列表  

  49.   

  50.             //由于库存Stock表开始没有设计资源有关的字段,暂时用User字段代替  

  51.             Expression<Func<Stock, bool>> exp = u => orgs.Contains(u.OrgId) && (u.User == "" || keys.Contains(u.User));  

  52.             var stocks = _repository.Find(pageindex, pagesize, "", exp);  

  53.             int total = _repository.GetCount(exp);  

  54.   

  55.   

  56.             return new  

  57.             {  

  58.                 total = total,  

  59.                 list = stocks,  

  60.                 pageCurrent = pageindex  

  61.             };  

  62.         }  

  63.   

  64.         public Stock Find(int id)  

  65.         {  

  66.             var stock = _repository.FindSingle(u => u.Id == id);  

  67.             if (stock == nullreturn new Stock();  

  68.   

  69.             return stock;  

  70.         }  

  71.   

  72.         public void Delete(int id)  

  73.         {  

  74.             _repository.Delete(id);  

  75.         }  

  76.   

  77.         public void AddOrUpdate(Stock stock)  

  78.         {  

  79.   

  80.             if (stock.Id == 0)  

  81.             {  

  82.                 _repository.Add(stock);  

  83.             }  

  84.             else  

  85.             {  

  86.                 _repository.Update(stock);  

  87.             }  

  88.   

  89.         }  

  90.     }  

  91. }  

OpenAuth.Repository 系统仓储层,实现领域模型中定义的接口

OpenAuth.App 应用层,为界面提供接口

OpenAuth.Mvc 采用基于jquery与bootstrap的B-JUI界面,1.0版中全面实现HTML,javascript,MVC后端代码的分离。如进出库管理加载的执行流程如下:

OpenAuth.UnitTest 单元测试

Infrastructure 与项目无关的通用工具集合

 

近期规划

功能:

5月份完成权限继承机制;

6月份增加完整的自定义流程事例;

性能:

添加完成的缓存机制;

结构:

根据反馈情况,把结构向真正的DDD方向调整。实现CQRS,适当时候添加AES等机制;

 

在线演示

在线地址:http://115.28.10.123:1314 (为安全起见,关闭了部分POST请求,如确实有演示修改的请求请留言)

首次发布QQ群:484498493

原文地址:http://www.cnblogs.com/yubaolee/p/OpenAuthNet.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

24.原生磁盘的使用

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》&#xff0c;内容非常棒&#xff0c;墙裂推荐&#xff1b; 2.磁盘操作抽象 第1层抽象&#xff1a;通过盘块号读写磁盘&#xff08;或逻辑盘块号&#xff09;&#xff1b;第2层抽象&#xff1a;用队列缓存多个…

Oracle入门(十三C)之高级查询(下)

上章&#xff1a;Oracle入门&#xff08;十三B&#xff09;之高级查询&#xff08;上&#xff09; 四、常见组函数 SUM、AVG、COUNT、MIN、MAX分组函数忽略null 值。不能在WHERE 子句中使用组函数。MIN 和MAX 可用于任何数据类型&#xff1b;SUM、AVG只能用于数字数据类型五、子…

微软将降低Visual Studio对操作系统的影响

在过去几年中&#xff0c;为了将Visual Studio变成Windows上的第一开发工具&#xff0c;而不管用户的目标平台是什么&#xff0c;微软作出了重大努力。最近收购Xamarin及通过大力支持开源工具来支持非Windows设备&#xff0c;极大地增加了它对于各类开发人员的用处。这一做法的…

代码设置margintop_关于元素设置margin-top能够改变body位置的原因及解决(子元素设置margin-top改变父元素定位)...

关于元素设置margin-top能够改变body位置的原因及解决(子元素设置margin-top改变父元素定位)起因&#xff1a;在进行bootstrap的.navbar-brand内文字设置垂直居中时采用line-height高度&#xff0c;无法居中&#xff0c;发现源码.navbar-brand 设置了 padding: 15px 15px;(默认…

Oracle入门(九A)之用户的权限或角色

转载自 查看Oracle用户的权限或角色 前几天被问到一些关于权限和角色的问题&#xff0c;今天抽时间总结一下如何查看Oracle用户的权限或角色&#xff0c;在之前的博文中&#xff0c;写过 SYS,SYSTEM,DBA,SYSDBA,SYSOPER的区别与联系 以及 Oracle中定义者权限和调用者权限案例分…

25.从生磁盘到文件

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》&#xff0c;内容非常棒&#xff0c;墙裂推荐&#xff1b; 2.文件&#xff1a;煮熟的磁盘&#xff0c;或熟磁盘&#xff1b; 本节的主要内容是讨论 如何从文件得到盘块号&#xff1b; 3.磁盘操作抽象&#xf…

Storm 1.0.1发布 .NET 适配也已到来

Apache Storm 1.0.0刚发布不久&#xff0c;1.0.1版本也在几天前到来&#xff1b;该版本主要是完成一些BUG修复和小的改进&#xff0c;通过一段时间新版本的使用&#xff0c;特将个人感受和一些遇到的问题归纳如下&#xff1b;另外 .NET 版本的 Storm 适配器也已经发布&#xff…

布隆过滤器速度_详解布隆过滤器的原理、使用场景和注意事项

今天碰到个业务&#xff0c;他的 Redis 集群有个大 Value 用途是作为布隆过滤器&#xff0c;但沟通的时候被小怼了一下&#xff0c;意思大概是 “布隆过滤器原理都不懂&#xff0c;还要我优化&#xff1f;”。技术菜被人怼认了、怪不得别人&#xff0c;自己之前确实只是听说过这…

Oracle入门(十四)之PL/SQL

一、PL/SQL 基本语法 PL/SQL语言是模块式的过程化SQL,是oracle公司对SQL的扩展。 &#xff08;1&#xff09;&#xff08;2&#xff09;&#xff08;3&#xff09;&#xff08;5&#xff09;&#xff08;6&#xff09;&#xff08;7&#xff09;数据类型Number 数字型Varchar2 …

26.文件使用磁盘的代码实现

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》&#xff0c;内容非常棒&#xff0c;墙裂推荐&#xff1b; 2.文件内容复习&#xff1a; 1&#xff09;如何从生磁盘抽象为文件&#xff1f; 核心是从字符流位置算出盘块号&#xff1b;2&#xff09;如何算出盘…

.NET Core全新的配置管理[共9篇]

提到“配置”二字&#xff0c;我想绝大部分.NET开发人员脑海中会立马浮现出两个特殊文件的身影&#xff0c;那就是我们再熟悉不过的app.config和web.config&#xff0c;多年以来我们已经习惯了将结构化的配置信息定义在这两个文件之中。到了.NET Core的时候&#xff0c;很多我们…

redis存opc_KEPServerEX6完整免费版

KEPServerEX6完整免费版是一款先进的连接平台&#xff0c;主要用于为您的应用程序提供单一来源的工业自动化数据&#xff0c;通过连接、管理、监视和控制不通的自动化设备和应用程序来实现工业数据。具有严谨的技术特征&#xff0c;支持多达250种以上的通讯协定&#xff0c;可连…

Oracle入门(十四B)之PL/SQL异常处理

定义&#xff1a;程序执行过程的警告或错误成为例外(Exception) 一、常见预定义错误 二、非预定义错误及用户定义错误 &#xff08;1&#xff09;非预定义oracle错误其他标准的oracle错误,可以自定义异常名&#xff0c;将其与指定oracle错误关联&#xff0c;由系统触发。 例子…

C#读书雷达 | TW洞见

大家都知道&#xff0c;ThoughtWorks的技术雷达每年都会发布两到三次&#xff0c;它不但是业界技术趋势的标杆&#xff0c;更提供了一种卓有成效的方法论&#xff0c;即打造自己的技术雷达。在这种思想的驱动下&#xff0c;我们诞生了自己的读书雷达。但这份雷达略显high level…

27.目录与文件系统

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》&#xff0c;内容非常棒&#xff0c;墙裂推荐&#xff1b; 2.第4层抽象&#xff1a;抽象整个磁盘到文件系统 【1】文件系统&#xff0c;抽象整个磁盘&#xff08;第4层抽象&#xff09; 【图解】整个磁盘抽象1…

dd命令打包多个文件_linux的tar命令详情;linux多个文件压缩打包到一个压缩文件...

tar命令可以用来压缩打包单文件、多个文件、单个目录、多个目录。Linux打包命令_tartar命令可以用来压缩打包单文件、多个文件、单个目录、多个目录。常用格式&#xff1a;单个文件压缩打包 tar czvf my.tar.gz file1多个文件压缩打包 tar czvf my.tar.gz file1 file2,...(file…

28.文件目录解析代码实现

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》&#xff0c;内容非常棒&#xff0c;墙裂推荐&#xff1b; 背景&#xff1a; 磁盘格式化后&#xff0c;其组成部分包括引导块&#xff0c;超级块&#xff0c;inode使用位图&#xff0c;盘块使用位图&#xff0…

Oracle入门(十四A)之PL/SQL 基本结构

一、条件控制语句 &#xff08;1&#xff09;条件语句Iif…then…end if形式1:if <布尔表达式> then…(pl/sql和sql)…end if;&#xff08;2&#xff09;条件语句II if…then…else … end if 形式2&#xff1a;if <布尔表达式> then…(pl/sql和sql)else…end if;…

利用记事本创建一个ASP.NET Core RC2 MVC应用

步骤一、安装最新的.NET Core SDK 我们可以根据自身的操作系统环境从https://github.com/dotnet/cli上下载.NET Core最新的SDK&#xff0c;这个SDK包含.NET Core Runtime和一些有用工具&#xff08;比如命令行&#xff09;。如果你已经安装了老旧的版本&#xff0c;我个人建议你…

datatable中某一列最小值_获取DataTable 某一列所有值

//获取某一列值string orderids (from d in dt.AsEnumerable() select d.Field("OrderID")).ToList().ListToString();/// /// 判断字符串是否在某字符串数组当中/// /// /// /// public static bool In(this string value, params string[] items){return items.An…