zoukankan      html  css  js  c++  java
  • 基于DDDLite的权限管理OpenAuth.net 1.0版正式发布

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

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

    main

    项目简介

            本项目采用经典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等模块并且能够实现系统的业务逻辑,基本就是了。如下图:

    clipboard

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

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

    • 领域对象:系统核心对象;
    • 领域接口:当前主要是数据库访问的仓储接口,具体的实现在OpenAuth.Repository中实现;
    • 领域服务:系统的多对象交互业务处理。由于当前的业务复杂度比较低,业务主要是以领域服务的形式出现。如项目中的“进出库管理服务”:
    using System;
    using System.Linq;
    using System.Linq.Expressions;
    using OpenAuth.Domain.Interface;
    
    namespace OpenAuth.Domain.Service
    {
        /// <summary>
        /// 领域服务
        /// <para>进出库管理服务</para>
        /// </summary>
        public class StockManagerService
        {
            private IStockRepository _repository;
            private IOrgRepository _orgRepository;
            private AuthoriseService _authoriseService;
    
            public StockManagerService(IStockRepository repository,
                IOrgRepository orgRepository, AuthoriseService service)
            {
                _repository = repository;
                _orgRepository = orgRepository;
                _authoriseService = service;
            }
    
            /// <summary>
            /// 根据部门ID得到进出库信息
            /// </summary>
            public dynamic Load(string username, int orgId, int pageindex, int pagesize)
            {
    
                _authoriseService.GetUserAccessed(username);
                if (_authoriseService.Orgs.Count == 0) //用户没有任何可见机构
                {
                    return new
                    {
                        total = 0,
                        pageCurrent = pageindex
                    };
                }
    
                var orgIds = _authoriseService.Orgs.Select(u => u.Id).ToArray();  //用户可访问的机构ID
    
                var orgs = _orgRepository.GetSubWithOwn(orgId)   //点击的节点与用户可访问的机构合并
                    .Where(u => orgIds.Contains(u.Id))
                    .Select(u => u.Id).ToArray();
    
                var keys = _authoriseService.Resources.Select(r => r.Key);    //用户可访问的资源的KEY列表
    
                //由于库存Stock表开始没有设计资源有关的字段,暂时用User字段代替
                Expression<Func<Stock, bool>> exp = u => orgs.Contains(u.OrgId) && (u.User == "" || keys.Contains(u.User));
                var stocks = _repository.Find(pageindex, pagesize, "", exp);
                int total = _repository.GetCount(exp);
    
    
                return new
                {
                    total = total,
                    list = stocks,
                    pageCurrent = pageindex
                };
            }
    
            public Stock Find(int id)
            {
                var stock = _repository.FindSingle(u => u.Id == id);
                if (stock == null) return new Stock();
    
                return stock;
            }
    
            public void Delete(int id)
            {
                _repository.Delete(id);
            }
    
            public void AddOrUpdate(Stock stock)
            {
    
                if (stock.Id == 0)
                {
                    _repository.Add(stock);
                }
                else
                {
                    _repository.Update(stock);
                }
    
            }
        }
    }
    

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

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

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

    image

    OpenAuth.UnitTest 单元测试

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

    近期规划

    功能:

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

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

    性能:

    添加完成的缓存机制;

    结构:

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

    在线演示

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

    首次发布QQ群:484498493

  • 相关阅读:
    SpringBoot:第五篇 CommandLineRunner
    多列单个索引和联合索引的区别
    数据库从0到0.1 (一): LSM-Tree VS B-Tree
    SpringBoot:第四篇 集成Guava(本地缓存+分布式缓存)
    SpringBoot:第三篇 配置修改
    TSINGSEE青犀视频编译WebRTC Android版报错The only supported distros are xxxxxxx处理方式
    TSINGSEE青犀视频开发WebRTC视频推流播放平台前端获取视频流列表错误是什么原因?
    如何修改TSINGSEE青犀视频开发的多平台支持视频RTSPServer组件EasyRTSPServer-win的端口号?
    视频RTSPServer组件EasyRTSPServer-win测试视频无法拉取到流在VLC播放如何修复?
    TSINGSEE青犀视频开发EasyWasmPlayer H265播放器是如何实现视频截图功能的?
  • 原文地址:https://www.cnblogs.com/yubaolee/p/OpenAuthNet.html
Copyright © 2011-2022 走看看