CRUD全栈式编程架构之更精简的设计
精简的程度
- ViewModel精简
- 服务精简
- 控制器精简
- Index.cshmtl精简
- AddOrEdit.cshtml精简
效果:最精简的情况下,只需要写Entity这一个数据库实体然后加上一些简单标记即可, 一般情况也只需要写TSearch,TOrder的逻辑可以
ViewModel精简
- 首先明确,因为Entity是codefirst生成数据库的前提,所以这个是必须有的。但是很多情况下 ViewModel和Entity属性一样,这个时候我们可以无需创建ViewModel,让Entity继承自IViewModel 即可将ViewModel精简掉。
- 注意服务中Convert方法不能去掉,由于ef代理对象的存在,直接暴露代理对象到界面层, 如果界面层修改代理对象,并且调用了工作单元的提交,那么实体就会被更新。也许这个bug你会找很久 ,所以Convert方法必须保留
服务的精简
- 第一步我们将Curd服务上的abstract去掉,
- 假设我们知道TEntiy,TModel,TOrder,TSearch的类型就可以通过反射创建出Crud服务了, 那么我们需要将上面四个泛型类型绑定到一起即可,我们可以定义一个类CrudCoden,这个类包含四个 属性,属性的类型都是Type,作用就是用来标识这四个泛型类型.
- 我们设计一个函数,入参是CurdCoden,出参是Curd服务的类型和Curd服务接口类型.通过反射即可构造
- 填充CrudCoden,我们将CrudCoden继承自Attribute,然后给出构造函数传入 TOrder,TModel,TEntity,TSearch,可以重载多个,这样直接标记在TEntity上即可完成CrudCoden的构造
- 注册服务 跟Repository的构造类似,反射程序集,然后获取所有的CurdCodenAttribute,然后 之前的函数获取Crud服务类型和接口类型,然后用Ioc注册即可,。
控制器的精简
- 控制器的注册和Crud服务类似,只是这个不需要接口
- 控制器激活,假设前台传入的url为user/index这种,这时,我们可以拿到controller的类型为user 然后通过反射获取到Entity的类型,这样就可以拿到Crud控制器类型,即可激活控制器
- 注意Url的配置,之前因为定义了Controller的类型,mvc会默认采用{名称}Controller中名称 作为Url中Controller部分的惨呼声,那么在配置url的时候,我们这里默认就采用Entity的名字显式 指定为Contoller参数
Index.cshtml精简
- Controller的返回不在直接是View()这样,我们显式指定未Shared的Index.cshtml页面, 然后页面的Model为dynamic,然后在querysection部分直接Html.EditForModel()即可
- Crud这些按钮也不是都需要,同样通过标记,在Entity上给出自定义Attribute,配置那些功能, 然后在页面上反射获取,如果没有标记,默认为全部.
AddOrEdit.cshtml精简
这里精简和Index.cshtml中类似,指定到特定页面,用dynamic传递模型,用EditForModel生成页面
菜单
这里同样可以通过标识,标识这个实体的Crud可以挂在那个菜单相面,在初始化的时候直接读取 标记即可
几个过程
程序启动过程
- 反射初始化菜单
- 注册Repository
- 注册服务
- 注册控制器
菜单点击过程
- 解析出Url中Controller对应的那个Entity,
- 用IocResolve出Controller,由于使用Ioc,只要构造过类型就可以递归创建
- 执行Action返回index.html页面
- 获取Entity上操作配置,生成页面返回到浏览器
- 调用Html.EditForModel生成页面
- Js调用查询方法获取数据
按钮点击过程
- 解析出Url中Controller对应的那个Entity,
- 用Ioc解析出Controller,由于使用Ioc,只要构造过类型就可以递归创建
- 执行Action返回操作页面
- 调用Html.EditForModel生成页面
- 提交数据(这里默认提交到当前url)
- 重复上述1,2两步,然后提交数据
GetFilter和GetOrder
这两部分需要扩展到TSearch和TOrder的类中即可,并且在SearchBase和OrderBase中声明 虚方法,给出默认实现和Crud服务中一样,然后子类实现
注意
- 这种精简模式并不和之前的冲突,如果有显式实现的Curd服务和控制器则使用精简模式。
- TModel的精简可根据情况使用
- 为了性能考虑,请多做一些缓存
- 精简模式下,其实TModel搭配attribute可以更灵活的实现编辑页面,吧Html.EditForModel 重写掉可以更大程度的是编辑页面灵活
总结
上面已经把实现要做的所有细节都说清楚了,只要按照说明写代码实现即可,最难也就是反射 和attribute的运用了,这两个使用是程序员进阶的必经之路,所以还是必须会的。由于这个设计 其实是一个反模式,太过于集中并且太依赖于配置,调试也相对麻烦。 但是他有一个好处就是帮你少写代码,有时候为了少写些代码很多事情都是值得去尝试的。 如果实现起来遇到什么麻烦,请留言我会一一解答。 代码根本没有思想重要。思想都不重视,代码只是复制粘贴而已。
CRUD全栈式编程架构之更精简的设计的更多相关文章
- CRUD全栈式编程架构之导入导出的设计
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- CRUD全栈式编程架构之MVC的扩展设计
MVC执行流程 路由的扩展 我理解的路由作用有以下几个 Seo优化,用“/”分开的url爬虫更爱吃 物理和逻辑文件分离,url不再按照文件路径映射 Controller,Action的选择 MVC路由 ...
- CRUD全栈式编程架构之数据层的设计
CodeFirst 一直以来我们写应用的时候首先都是创建数据库 终于在orm支持codefirst之后,我们可以先建模. 通过模型去创建数据库,并且基于codefirst可以实现方便的 实现数据库迁移 ...
- CRUD全栈式编程架构之界面层的设计
Layout的设计 模板模式 mvc的模板特别类似设计模式中模板方法模式,结合Layout中RenderSection和RenderBody方法可以将部分html展现逻辑延迟到具体的视图页面去实现里面 ...
- CRUD全栈式编程架构之服务层的设计
服务层代码 首先我先放出2个主要类的代码再分别讲解 接口 using System; using System.Collections.Generic; using System.Linq; usin ...
- CRUD全栈式编程架构之控制器的设计
页面 这里界面我采用jquery miniui来做的,当你完全了解了整个设计之后可以轻松切换到其他的js框架,个人认为类似muniui,easyui等等这类可以将web界面做得和winform类似的框 ...
- CRUD全栈式编程架构总结
这里放出实例代码 github.com/SkyvenXiong/HCC
- CRUD全栈式编程概述
业务场景 CRUD,从数据驱动的角度几乎所有的的业务都是在做这样的事情. 几乎所有的操作都是在做对表的增删改查. 假设我们将数据库数据规个类: 分为基础/配置数据和业务/增长数据,或者说静态数据 ...
- 全栈式JavaScript
如今,在创建一个Web应用的过程中,你需要做出许多架构方面的决策.当然,你会希望做的每一个决定都是正确的:你想要使用能够快速开发的技术,支持持续的迭代,最高的工作效率,迅速,健壮性强.你想要精益求精并 ...
随机推荐
- LocalDate test
import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.tim ...
- String转不同type的类对象
import org.springframework.beans.SimpleTypeConverter; private Object deserializeValue(Class<?> ...
- PHP任意文件上传漏洞(CVE-2015-2348)
安全研究人员今天发布了一个中危漏洞——PHP任意文件上传漏洞(CVE-2015-2348). 在上传文件的时候只判断文件名是合法的文件名就断定这个文件不是恶意文件,这确实会导致其他安全问题.并且在这种 ...
- ruby 更换源 + sass 安装
gem sources -c #删除所有镜像地址 gem sources -a http://gems.ruby-china.com #添加ruby-china的镜像地址 原有的org域名更换变成co ...
- 新磁盘创建lvm并挂载
### .查看硬盘 fdisk -l ### 删除分区 fdisk /dev/sdc ### 按d删除,按w保存并退出 ### 创建pv pvcreate /dev/sdc ### 创建 vg vgc ...
- RequestContextHolder与RequestContextUtils
org.springframework.web.servlet.support.RequestContextUtils 在spring-webmvc中, 主要用来获取WebApplicationCon ...
- python_文件 处理
一.字符编码 内存固定使用unicode编码 数据最先产生于内存中,是unicode格式,要想传输需要转成bytes格式 # unicode -------> enconde( u t f - ...
- [转]Passing data between pages in JQuery Mobile mobile.changePage
本文转自:http://ramkulkarni.com/blog/passing-data-between-pages-in-jquery-mobile/ I am working on a JQue ...
- 手机缺失sqlite3时操作数据库的多种解决方案 ----adb命令科普
在Android应用开发无处不在SQLite数据库的身影.那么在开发中怎么使用adb命令操作数据库的功能呢? 下面我们将完整的介绍与数据库操作相关的命令集及当手机缺少sqlite3的时候的多种解决方案 ...
- python函数(四)
一.函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,编程中的函数在英文中也有很多不同的叫法.在BASIC中叫做subroutine(子过程或子程序),在Pasc ...