系列目录
前言:
这应该是本系统最后一次重构,将重构BLL层和Model层。来完全取代代码生成器生成的BLL层和DAL层。完全废掉了代码生成器的DAL,BLL,MODEL层。
全自动生成增,删,改,查的通用方法和模型转换与BLL层的模型事务脱离,后续文章,会以一些插件或功能为目的,继续完善,进行分享,最后60节的文章会对本系统做一个总结
(但是还没时间写,相信60节的文章能让你快速了解到本系统的优势和架构,就算你从未阅读之前的所有文章)
继上次的DAL层重构(上一节),本来只想重构DAL层算了,但是鉴于本人是代码强迫症患者,所以花了些时间把BLL层重构。
在此务必共鸣一个问题,代码重构不是架构改变,这个系统的架构完全还是原来的接口多层注入架构!如下图所示完全不变
最后必须让初学者理解一个知识点:分部类 partial 关键字,因为我们的重构是围绕分部类而实现,包括接口
partial 关键字指示可在命名空间中定义该类、结构或接口的其他部分。所有部分都必须使用 partial 关键字。在编译时,各个部分都必须可用来形成最终的类型。各个部分必须具有相同的可访问性,如 public、private 等。
如果将任意部分声明为抽象的,则整个类型都被视为抽象的。如果将任意部分声明为密封的,则整个类型都被视为密封的。如果任意部分声明基类型,则整个类型都将继承该类。
指定基类的所有部分必须一致,但忽略基类的部分仍继承该基类型。各个部分可以指定不同的基接口,最终类型将实现所有分部声明所列出的全部接口。在某一分部定义中声明的任何类、结构或接口成员可供所有其他部分使用。最终类型是所有部分在编译时的组合。
下列声明:
partial class Earth : Planet, IRotate { } partial class Earth : IRevolve { }
等效于下列声明:
class Earth : Planet, IRotate, IRevolve { }
1.改变现状
相比我们DAL层,重构BLL层是有技术难度的,因为业务层涉及模型的转换构成,虽然只重构模块的(增、删、改、查),下面我们开始
下载上一节代码(https://yunpan.cn/cYUdjssbmiLrL 访问密码 e622)来分析业务层。
分析:IBLL,BLL
IBLL层不用说了,跟IDAL层是一致的
所以我们直接复制IDAL的TT模版修改后如下
非常好。业务层完成跟预期是一样的!这样我们直接可以看到我们原来的ISysSample可以由
using System.Collections.Generic; using Apps.Common; using Apps.Models.Sys; namespace Apps.IBLL { public interface ISysSampleBLL { List<SysSampleModel> GetList(ref GridPager pager, string queryStr); bool Create(ref ValidationErrors errors, SysSampleModel model); bool Delete(ref ValidationErrors errors, string id); bool Delete(ref ValidationErrors errors, string[] deleteCollection); bool Edit(ref ValidationErrors errors, SysSampleModel model); SysSampleModel GetById(string id); bool IsExist(string id); } }
变为--->
using System.Collections.Generic; using Apps.Common; using Apps.Models.Sys; namespace Apps.IBLL { public partial interface ISysSampleBLL { } }
代码行数发生质的改变,可以我们就可以扩展自己的接口方法,利用partial类
照样画葫芦,业务层也生成
直接上TT代码
由于每一个业务模型的属性都不一致,这里不能用List<T>来做,所以,一个表会生成一个BLL类。(图中红色部分)
如果生成红色部分。主要看下面代码
<# if (simpleProperties.Any()) { foreach(var edmProperty in simpleProperties) { #> <#=edmProperty#> = r.<#=edmProperty#>, <# } } #>
获取表模型的所有属性,所有这段对很多人是有帮助的,请收藏,说不定你以后要用到
OK,编译通过,运行正确,还是熟悉的面孔
但是至此。我们的业务层和数据访问层,可以说是一行代码都没写。足够体现了TT模版的强大之处,相比我们之前要用代码生成器来得极其方便
2.引发问题
直到上面步骤,一切都很顺利,没有一点不妥。
有经验的园友会发现,里面东西都是写死的。而且分部类不可以重写自己。
比如说。我在处理 entity.Name = model.Name;时候我想entity.Name = model.Name.TrimStart() 去掉字符串前面的空格,那么可以看到根本无法操作。
然而我们需要重写,但是又发现无法重写分部类的方法,怎么做?必须用一张图来看,我是这么做的
- 绿色是我们已经重构完成的。
- 紫色是我们需要重构的一个TT模版,这是所有都是虚方法的类
- 粉色是我们自己扩张的业务方法,目前为空
虚方法是可以重写的关键字是virtual 以下重写之后优先级高于前者 用override。用代码来说明
改变一下CommonBLL.tt
更Common代码基本一致,只是头部变了,文件名称变了
public class Virtual_SysSampleBLL
那么重新创建一个CommonBLL.tt
代码生成后如下,什么都没有实现继承接口,和上面的TT模版的类
namespace Apps.BLL { public partial class SysSampleBLL: Virtual_SysSampleBLL,ISysSampleBLL { } }
好吧,我只是想省掉写: Virtual_SysSampleBLL,ISysSampleBLL
OK,运行之后还是熟悉的面孔,但是可以重载了,我们重载一下,好处理我们的业务!
新建SysSampleBLL.cs
namespace Apps.BLL { public partial class SysSampleBLL { public override bool Create(ref ValidationErrors errors, SysSampleModel model) { try { SysSample entity = m_Rep.GetById(model.Id); if (entity != null) { errors.Add(Resource.PrimaryRepeat); return false; } entity = new SysSample(); entity.Id = model.Id; entity.Name = model.Name.TrimStart(); entity.Age = model.Age; entity.Bir = model.Bir; entity.Photo = model.Photo; entity.Note = model.Note; entity.CreateTime = model.CreateTime; if (m_Rep.Create(entity)) { return true; } else { errors.Add(Resource.InsertFail); return false; } } catch (Exception ex) { errors.Add(ex.Message); ExceptionHander.WriteException(ex); return false; } } } }
同样的。我们可以对Model层进行重构,类似BLL层。利用虚属性,可以对属性进行注解。来获得优先级,和一次生成编译通过
//------------------------------------------------------------------------------ // <auto-generated> // 此代码已从模板生成。 // // 手动更改此文件可能导致应用程序出现意外的行为。 // 如果重新生成代码,将覆盖对此文件的手动更改。 // </auto-generated> //------------------------------------------------------------------------------ using Apps.Models; using System; namespace Apps.Models.Sys { public class Virtual_SysSampleModel { public virtual string Id { get; set; } public virtual string Name { get; set; } public virtual Nullable<int> Age { get; set; } public virtual Nullable<System.DateTime> Bir { get; set; } public virtual string Photo { get; set; } public virtual string Note { get; set; } public virtual Nullable<System.DateTime> CreateTime { get; set; } } }
//------------------------------------------------------------------------------ // <auto-generated> // 此代码已从模板生成。 // // 手动更改此文件可能导致应用程序出现意外的行为。 // 如果重新生成代码,将覆盖对此文件的手动更改。 // </auto-generated> //------------------------------------------------------------------------------ using Apps.Models; using System; namespace Apps.Models.Sys { public partial class SysSampleModel:Virtual_SysSampleModel { } }
然后自己建Model对其重载
本文转自ymnets博客园博客,原文链接:http://www.cnblogs.com/ymnets/p/5399190.html,如需转载请自行联系原作者