天天看點

項目架構開發:展現層(下)

上一章我們完成了項目的展現層的一個表的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!!

繼續閱讀