基于.NET6的简单三层管理系统
前言
笔者前段时间搬砖的时候,有了一个偷懒的想法:如果开发的时候,简单的CURD可以由代码生成器完成,相应的实体、服务都不需要再做额外的注册,这样开发人员可以省了很多事。
于是就开了这个项目,期望实现这样的能力:业务人员只需关注实体的构建,业务服务的编写,以及路由的配置。
让业务的开发,变成简单的三步走:创建实体 >> 业务开发 >> 路由配置。
目前项目构思的绝大部分能力已完成(代码生成器、定时任务还未实现),现将项目发布,希望能对搬砖的大家伙有所帮助。
项目概述
前后端分离,使用 JWT 认证。
后端:基于 .NET6 和 EF Core,集成常用组件,采用传统三层结构。
前端:基于 小诺1.8 做适配,主技术栈:Vue2.6.x、Ant-Design-Vue
体验地址
管理员:superAdmin 密码:123456
普通用户:user 密码:123456
快速开始
请参考项目文档:使用手册
参考项目
注:排名不分先后。
感谢这些优秀的开源项目!
基本设计思路
- 依赖于抽象 - 依赖倒置原则,控制反转(IoC) 
- 切面编程(AOP) - 权限、日志、异常等通过过滤器(Filter)或中间件(Middleware)等实现,集中编程 
- 可配置 
- 自动注册 - 自动注册实体(Entity)、自动注册服务类(Service)等 
项目结构
项目结构构思

主要分为三层:Interface表现层、Services服务层、Repository仓储层
Interface:Host依赖所有层,完成程序配置(如:Program.cs 中DI容器注入服务,中间件管道配置等);Web API 配置路由,提供 API 接口,如果程序以后有迁移、或替换前端的情况,也可以在这里做一层适配器(注:API只是一种表现形式,也可以为MVC)
Services:所有的业务都在这一层。从仓储中读取数据模型(Models),进行业务操作,返回DTO(Data transfer objects)给表现层。
Repository:数据库访问。
通用的模块:Model、Common、Framework
Models:包含所有数据模型,如 Entity(对象数据库的数据表)、CacheItem缓存对象、EventModel事件模型等。
Common:集成常用组件,根据项目需要做相应配置;提供基础服务,如CurrentUser访问当前用户信息;提供静态帮助类,所有无状态的函数都归入此类,如GuidHelper.Next() 产生连续 Guid。
Framework:框架,比如引用ABP或Furion等框架,甚至是自己项目一些通用的能力,可以到处用的。
实际项目结构
实际上,把 IServices 和 IRepository 此类接口层干掉了。
Models 则归入了对应的使用者里面,Framework 也没有。
Common        # 基础设施:集成常用组件;提供基础服务;提供静态帮助类
Repository    # 仓储层:数据库访问,数据库迁移
Services      # 服务层:业务实现
WebApi        # 表现层:完成程序配置;配置路由,提供API接口
目录结构如下,更详细的结构,请查看文档。
├─config                  # 一些配置文件,如:redis 的配置文件
├─doc                     # 项目文档
├─web                     # 前端
├─webapi                  # 后端
   ├─Simple.Common        # 基础设施
   ├─Simple.Repository    # 仓储层
   ├─Simple.Services      # 服务层
   └─Simple.WebApi        # 表现层
业务能力
- 组织架构
- 组织机构(organization)
- 岗位(position)
- 用户(user)
 
- 权限管理
- 应用(application)
- 菜单(menu)
- 角色(role)
 
- 开发管理
- 数据字典(dictionary、dictionaryItem)
 
- 日志管理
- 操作日志(log operating)
- 异常日志(log exception)
 
系统能力
- 认证:集成Cookies、JWT;默认启用 JWT
- 授权:基于策略(Policy)的授权
- ORM:EF Core 的 Code First 模式
- 依赖注入:默认 DI 容器,实现自动注入
- 缓存:IDistributedCache,默认注入 Memory Cache,可替换 Redis
- 日志:NLog
- 事件总线:默认启用 BackgroupService,基于Channel 实现的单机版发布订阅;可替换为 Redis 的发布订阅(可用于分布式);也可替换为 RabbitMQ 的发布订阅(可用于分布式)
- 定时任务:Quartz
- 数据验证:模型验证(Model validation)
- 对象映射:AutoMapper
项目亮点
一些Q&A
为什么把 IServices 这些接口层给干掉了,仅留下实现层?
答:一般项目中会如有 IRepository 和 IServices 这些个抽象层,主要是为了控制反转(IoC),实现项目各层之间解耦,最终目的就是为了“高内聚,低耦合”。
笔者认为,对于单体项目来说,做到高内聚即可,再追求完全的低耦合,会增加成本和困扰(举个简单的栗子:项目初期,业务大改是常有的事,改服务类的接口的事并不少见。除非说业务主体明确,需要修改的,并不是业务的接口,而是业务的具体实现)。
最后是这个项目,本就是为了追求最简三层单体。
为什么不对仓储额外封装一层?
答:简单的项目基本上是单数据库的,且 EF Core 已经实现了工作单元和仓储模式,可以不用再封装一层。
当然,笔者还是建议跟ABP框架那样再封装一层仓储,可以避免一些后续的开发运维问题(比如:系统迁移、重构等)。
基于.NET6的简单三层管理系统的更多相关文章
- 基于Java的简单银行管理系统(MVC设计模式)
		项目导航 功能展示 项目描述 项目结构 `data` `service` `utils` `view ` 欠缺与总结 源码下载 功能展示 本系统基于命令台窗口,暂未与图形页面结合.话不多说,先上效果图 ... 
- 基于mybatis设计简单信息管理系统---jsp页面
		1.在设计编辑界面的时候需要有一个下拉的列表页,想要他指定到指定的值: <select id="categoryId" name="categoryId" ... 
- 基于mybatis设计简单信息管理系统2
		1.空指针异常 public class CanvasServlet extends HttpServlet { private CanvasService canvasService; privat ... 
- 基于mybatis设计简单信息管理系统1
		驼峰式命名法 骆驼式命名法就是当变量名或函数名是由一个或多个单词连结在一起,而构成的唯一识别字时,第一个单词以小写字母开始:第二个单词的首字母大写或每一个单词的首字母都采用大写字母,例如:myFirs ... 
- C#仿google日历asp.net简单三层版本
		网上搜了很多xgcalendar的例子都是Php开发的,而且官方站上的asp.net/MVC版 在vs10 08 都报错. 所以自己重新用三层写了一下希望对大家有帮助 废话不多说了 先看看它都有些什么 ... 
- DoNet开源项目-基于jQuery EasyUI的后台管理系统
		博主在业余时间开发了一个简单的后台管理系统,其中用到了 jQuery EasyUI 框架,上次分享过系统布局,参考文章:jQuery EasyUI 后台管理系统布局分享,目前已完成系统的整体框架的搭建 ... 
- 运用Unity实现依赖注入[结合简单三层实例]
		运用Unity实现依赖注入[结合简单三层实例] 一:理论部分 依赖注入:这是 Ioc 模式的一种特殊情况,是一种基于改变对象的行为而不改变类的内部的接口编程技术.开发人员编写实现接口的类代码,并基于接 ... 
- 基于UML的高校教务管理系统的设计与实现
		一.基本信息 标题:基于UML的高校教务管理系统的设计与实现 时间:2018 出版源:南昌航空大学 领域分类:教育信息化:教务管理系统:UML:SSH:Oracle 二.研究背景 问题定义:高校教务管 ... 
- C#简单三层结构设计UI、BLL、DAL、Model实际项目应用例子
		C#简单三层结构设计UI.BLL.DAL .Model实际项目应用例子 在实际项目中,程序设计都有他的层次结构,比如MVC.MVP.普通的三层结构等等,不过现在用三层结构的相比可能少了,但是也有一些小 ... 
随机推荐
- 实战模拟│JWT 登录认证
			目录 Token 认证流程 Token 认证优点 JWT 结构 JWT 基本使用 实战:使用 JWT 登录认证 Token 认证流程 作为目前最流行的跨域认证解决方案,JWT(JSON Web Tok ... 
- CodeQL使用流程
			前言 好久没用CodeQL了,看了自己之前写的文章发现竟然没有做过相关记录 然后就不知道怎么用了hhh 使用流程 0x1 生成数据库 我们拿到一套源码,首先需要使用CodeQL生成数据库 执行命令: ... 
- Taurus.MVC 如何升级并运行在NET6、NET7
			前言: 之前计划帮某公司架构一个从WPF转向Web的低代码的开发平台,并构思为Taurus.MVC 新增微服务的基础功能模块,提供便捷的微服务开发方式,因中途合作中止,代码开发部分后续再上. 最近看到 ... 
- stringstrean类中关于clear和str的比较
			stringstream类涉及到多次类型转换的时候容易出现异常错误 因为第一次数据如果读入eof或者输出完整来到eof,此时stringstream会自动为其添上eofbit标志位,此时继续进行任何操 ... 
- 第三天python3 字典
			字典 dict 特点:key-value键值对的数据的集合 可变的.无序的.key不重复:非线性结构: 字典的初始化 d=dict() 或者 d = { } dict(**kwargs) 使用n ... 
- 关于又拍云免费cdn全网加速服务的长期评测(各种踩坑)
			原文转载自「刘悦的技术博客」 ( https://v3u.cn/a_id_128 ) 妇孺皆知,前端优化中最重要的优化手段之一就是cdn加速,所谓cdn加速就是采用更多的缓存服务器(CDN边缘节点), ... 
- 当我们进行性能优化,我们在优化什么(LightHouse优化实操)
			好的互联网产品不仅仅在功能上要高人一筹,在性能层面也需要出类拔萃,否则金玉其外败絮其中,页面是美轮美奂了,结果首屏半天加载不出来,难免让用户乘兴而来,败兴而归. 幸运的是,前端的性能优化有诸多有迹可循 ... 
- 针对单个球体的World类
			好了,终于到了可以看到图片的环节了.之前的类,你一定要实现好了.所有关于World类的报错,现在我们一个一个解决来了. 先看看World类的声明: #pragma once #ifndef __WOR ... 
- 【Harmony OS】【ArkUI】ets开发 简易视频播放器
			前言:这一次我们来使用ets的Swiper组件.List组件和Video组件制作一个简易的视频播放器.本篇是以HarmonyOS官网的codelab简易视频播放器(eTS)为基础进行编写.本篇最主要 ... 
- 羽夏看Linux内核——中断与分页相关入门知识
			写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ... 
