CRUD全栈式编程架构之更精简的设计

精简的程度

  1. ViewModel精简
  2. 服务精简
  3. 控制器精简
  4. Index.cshmtl精简
  5. 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可以挂在那个菜单相面,在初始化的时候直接读取 标记即可

几个过程

程序启动过程

  1. 反射初始化菜单
  2. 注册Repository
  3. 注册服务
  4. 注册控制器

菜单点击过程

  1. 解析出Url中Controller对应的那个Entity,
  2. 用IocResolve出Controller,由于使用Ioc,只要构造过类型就可以递归创建
  3. 执行Action返回index.html页面
  4. 获取Entity上操作配置,生成页面返回到浏览器
  5. 调用Html.EditForModel生成页面
  6. Js调用查询方法获取数据

按钮点击过程

  1. 解析出Url中Controller对应的那个Entity,
  2. 用Ioc解析出Controller,由于使用Ioc,只要构造过类型就可以递归创建
  3. 执行Action返回操作页面
  4. 调用Html.EditForModel生成页面
  5. 提交数据(这里默认提交到当前url)
  6. 重复上述1,2两步,然后提交数据

GetFilter和GetOrder

这两部分需要扩展到TSearch和TOrder的类中即可,并且在SearchBase和OrderBase中声明 虚方法,给出默认实现和Crud服务中一样,然后子类实现

注意

  • 这种精简模式并不和之前的冲突,如果有显式实现的Curd服务和控制器则使用精简模式。
  • TModel的精简可根据情况使用
  • 为了性能考虑,请多做一些缓存
  • 精简模式下,其实TModel搭配attribute可以更灵活的实现编辑页面,吧Html.EditForModel 重写掉可以更大程度的是编辑页面灵活

总结

上面已经把实现要做的所有细节都说清楚了,只要按照说明写代码实现即可,最难也就是反射 和attribute的运用了,这两个使用是程序员进阶的必经之路,所以还是必须会的。由于这个设计 其实是一个反模式,太过于集中并且太依赖于配置,调试也相对麻烦。 但是他有一个好处就是帮你少写代码,有时候为了少写些代码很多事情都是值得去尝试的。 如果实现起来遇到什么麻烦,请留言我会一一解答。 代码根本没有思想重要。思想都不重视,代码只是复制粘贴而已。

原文地址:https://www.cnblogs.com/Skyven/p/5746073.html