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

  • 相关阅读:
    游标cursor
    SQL: EXISTS
    LeetCode Reverse Integer
    LeetCode Same Tree
    LeetCode Maximum Depth of Binary Tree
    LeetCode 3Sum Closest
    LeetCode Linked List Cycle
    LeetCode Best Time to Buy and Sell Stock II
    LeetCode Balanced Binary Tree
    LeetCode Validate Binary Search Tree
  • 原文地址:https://www.cnblogs.com/yubaolee/p/OpenAuthNet.html
Copyright © 2011-2022 走看看