项目架构开发:展现层(下)

上一章我们完成了项目的展现层的一个表的CURD,从此UI层到数据库的通道打通了;传送门:项目架构开发:展现层(上)

这章我们还是讲CURD,不过内容重复的话就没意思了,这次我们想办法提高代码编写的效率;

先来看看从UI层到DataAccess一共要写多少个类文件,服务层就先不算在里边了

 

1、DataAccess Layer

这部分是一次性的工作,完成后之后几乎不用修改,所以这个关系不大

 

2、Business Logic Layer

业务逻辑层有8个类需要写,以LoginUser举例

分别是:

1. LoginUser.cs

2. ILoginUserRepository.cs

3. LoginUserRepository.cs

4. LoginUserApplication.cs

5. ILoginUserApplication.cs

6. LoginUserRequest.cs

7. LoginUserResponse.cs

8. LoginUserApplicationTest.cs

 

3、展现层

9. LoginUserController.cs

10. LoginUserViewModel.cs

11. LoginUser/Index.cshtml

12. LoginUserControllerTest.cs

 

好了,一共12个,如果view及JS分多文件的话可能得有15个左右,要是服务层再加进来,恐怕得有18个左右

 

这不得不说多层架构也实在是够麻烦的,单单一个表结构的CURD就要写那么多的类,要是有几百个表,那工作量简直不敢想象;汗。。

相反要是普通的三层可能只有5个左右,而实际上按照学校里的教科书那样,一个不写也是可以完成的,直接在aspx.cs里边一个方法搞定;

 

但是既然选择了多层开发,这种情况肯定得有后续手段能解决掉; 我能想到的就是代码生成器了,这就是本章的主题

代码生成器有很多,比较有名的比如李天平的“动软”,记得刚入行的时候看到“动软”,崇拜的不行,好像现在还在维护的;

 

但是就是觉得动软的模板配置不灵活,太重了;后来自己搞了一个比较简单的代码生成器,传送门:代码生成器

具体就不介绍了,这次主要是演示一些结合代码生成器批量生产代码的威力;

因为在上一章我们已经有了上边12个类的已经运行成功的代码。所以我们就以这12个文件为模板,批量生成其他表的所有类

连测试类也不放过,因为生成后要单元测试的。

我们开始吧!

 

4、新增模板文件

 

应用逻辑类:{0}Application.cs

 1 using Business.DTO.Request;
 2 using Business.DTO.Response;
 3 using Business.ReverseDDD.IRepository;
 4 using Business.ReverseDDD.Model;
 5 using Business.ReverseDDD.Repository;
 6 using Infrastructure.Common;
 7 using Infrastructure.Data.UnitOfWork;
 8 using Infrastructure.Interface;
 9 using System;
10 using System.Collections.Generic;
11 using System.Linq;
12 using System.Linq.Expressions;
13 using Business.ReverseDDD.IApplication;
14 
15 namespace Business.ReverseDDD.Application
16 {
17     public class ${ClassName}Application : I${ClassName}Application
18     {
19         private IUnitOfWork<${ClassName}> unitOfWork;
20         private I${ClassName}Repository repository;
21 
22         public ${ClassName}Application()
23         {
24             this.unitOfWork = new UnitOfWork<${ClassName}>();
25             this.repository = new ${ClassName}Repository(this.unitOfWork);
26         }
27 
28         public bool Add(${ClassName}CURequest entity)
29         {
30             this.repository.Add(new ${ClassName}()
31             {
32 #foreach($Column in $ColumnList)
33 #if(${Column.StandardText}!="CreateTime")
34                 ${Column.StandardText} = entity.${Column.StandardText},
35 #end
36 #end
37                 CreateTime = DateTime.Now
38             });
39             this.unitOfWork.Commit();
40 
41             return true;
42         }
43 
44         public bool Update(${ClassName}CURequest entity)
45         {
46             var tmp = this.repository.Get(entity.Id);
47             if (tmp != null)
48             {
49 #foreach($Column in $ColumnList)
50 #if(${Column.StandardText}!="CreateTime")
51                 tmp.${Column.StandardText} = entity.${Column.StandardText};
52 #end
53 #end
54                 this.repository.Update(tmp);
55 
56                 this.unitOfWork.Commit();
57                 return true;
58             }
59 
60             return false;
61         }
62 
63         public bool Delete(Guid Id)
64         {
65             this.repository.Delete(Id);
66             this.unitOfWork.Commit();
67 
68             return true;
69         }
70 
71         public ${ClassName} Get(Guid Id)
72         {
73             return this.repository.Get(Id);
74         }
75 
76         public Tuple<int, IEnumerable<${ClassName}>> GetPage(Page page, Expression<Func<${ClassName}, bool>> order, Expression<Func<${ClassName}, bool>> where = null)
77         {
78             return this.repository.GetPage(page, order, where);
79         }
80     }
81 }

实体类:{0}.cs

 1 using System;
 2 using Infrastructure.Common;
 3 using System.ComponentModel.DataAnnotations;
 4 
 5 namespace Business.ReverseDDD.Model
 6 {
 7     public class ${ClassName} 
 8     {
 9         [Required]
10         [IgnoreProperty(true)]
11         public int RowNumber { get; set; }
12 
13 #foreach($Column in $ColumnList)
14 #if($Column.StandardType == "string")
15         /// <summary>${Column.Description}</summary>
16         public string ${Column.StandardText} { get; set; }
17 
18 #else
19 #if(${Column.StandardText}!="Id")
20         /// <summary>${Column.Description}</summary>    
21         public $Column.StandardType? ${Column.StandardText} { get; set; }
22 
23 #else
24         /// <summary>${Column.Description}</summary>
25         public $Column.StandardType ${Column.StandardText} { get; set; }
26 
27 #end
28 #end
29 #end
30     }
31 }

 

可以看到,所有类名都被{类名}替换掉了,而且支持循环字段,如这个:#foreach($Column in $ColumnList)

以及if语法,如这个:#if(${Column.StandardText}!="CreateTime")

 

5、我们把所有表需要生成模板批量导出来

 

好了,把文件拷贝进项目中

6、编译文件、运行单元测试

一个ERROR都没有,当然设置模板时要细心

103个测试用例全部通过,这初步保证了代码质量;

 

 7、预览UI界面

 

都运行正常,期间一句都没改过哦;当然有些细节肯定要调整的,比如在VIEW视图共性可能不多,很多细节可能需要调整

但是其他层都保证的CURD及GetPage、GetList,这已经完成了至少70%的代码,这真正做到了把主要经历放在业务逻辑层了

老板再也不用担心我的速度问题,so easy!!

 

posted @ 2017-03-13 23:39 蓝建荣 阅读(...) 评论(...) 编辑 收藏