看到這標題的朋友可能搞不懂到底在搞什么,不過不要緊有興趣的朋友可以先了解一下IVsSingleFileGenerator到底是用來做什么用的《實現自定義的VsSingleFileGenerator 》;在vs.net里提供一個IVsSingleFileGenerator接口可以方便地為項目文件生成附屬文件,如剛才那文章提到的根據XML文件自動生成一個附屬的C#代碼文件;當然這個IVsSingleFileGenerator并不只是針對XML文件,可以是隨便為任何項目文件生成附屬文件你只要在文件屬性中設置相關Custom Tools就可以了.
為什么在這里我提出在代碼文件的基礎上再生相關的代碼附屬文件呢,為什么不直接在原代碼文件寫完整就可以了;原因很簡單因為手寫代碼是沒有電腦來得快,最主要一個原因是基于XML的IVsSingleFileGenerator在某方面不好所以才采用基于代碼文件的方式作為代碼描述模板.用XML描述在現情況碰到的問題,在我的數據持久層里是采用XML結合IVsSingleFileGenerator來生成相關實體類的.
內容大概如下:
<SmarkDatamodels xmlns="http://SmarkData.cn/model.xsd" > <Class Name="Customer" Table="vp_Customer"> <ID Name="CustomerID" Type="System.Int64"/> <Property Name="UserName" Type="System.String" Comment="用戶名"/> <Property Name="UserPWD" Type="System.String" Comment="用戶密碼"/> <Property Name="CustomerType" Type="System.Int32" Comment="客戶類型"/> <Property Name="CustomerName" Type="System.String" Comment="自定義名"/> <Property Name="Sex" Type="System.Boolean" Comment="性別"/> <Property Name="Region" Type="System.String" Comment="地區"/> <Property Name="City" Type="System.String" Comment="城市"/> <Property Name="IDCard" Type="System.String" Comment="身份證號"/> <Property Name="EMail" Type="System.String" Comment="電子郵件"/> <Property Name="Phone" Type="System.String" Comment="電話"/> </Class> </SmarkDatamodels> VsSingleFileGenerator會根據XML生成以下相關實體: /// <summary> /// 用戶名 /// </summary> public virtual string UserName { get { return this.mUserName; } set { this.mUserName = value; this.EntityState.FieldChange("UserName"); } } /// <summary> /// 用戶密碼 /// </summary> public virtual string UserPWD { get { return this.mUserPWD; } set { this.mUserPWD = value; this.EntityState.FieldChange("UserPWD"); } } /// <summary> /// 客戶類型 /// </summary> public virtual int CustomerType { get { return this.mCustomerType; } set { this.mCustomerType = value; this.EntityState.FieldChange("CustomerType"); } }
|
VsSingleFileGenerator有個不好的地方就是當主文件修改后會重新生成附屬文件,這樣就導致你無法修改代碼文件.如果想為某些屬性成員添加Attribute來處理一些功能基本是沒辦法的.
如添加成員數據驗證:
[NotNull] [Length("5","16","用戶名長度必須在5-16個字符內!")] public string UserName { get; set; } |
即使能解決VsSingleFileGenerator生成附屬文件沖突問題;但也要面對另一個問題,就如何擴展XML來處理這些擴展呢,添加XMLSchema擴展描述規則,重寫VsSingleFileGenerator代碼生成部份;這樣下來沒多久我估計自己會瘋了....
實際情況添加不同Attribute來擴展輔助功能是很常見的事情,就一個驗證來說根據實際情況就有很多情況,類構造方式也不一樣.就針對這些情況來擴展XMLSchema和重寫VsSingleFileGenerator帶來的工作量就不用說了,還有一個問題就是XML并不能提供類型編譯的保證這樣對XML的質量是很難保證.
經過了一段時間的思考發現為什么不直接用代碼作為原模板呢,這樣就能得到IDE的支持,強在編譯器的支持下保證類型輸入規則的有效性.以下是本人實現的簡單生成模型:
[Table] interface IUser { [ID] string UserName { get; set; } string BirthDate { get; set; } string Region { get; set; } string Remark { get; set; } } |
生成的相關代碼
[Table] [Serializable] public class User:Smark.Data.Mappings.DataObject { [ID] public string UserName { get{ return mUserName;} set{mUserName=value;EntityState.FieldChange("UserName");} } private string mUserName; public static Smark.Data.FieldInfo userName = new Smark.Data.FieldInfo("User","UserName"); public string BirthDate { get{ return mBirthDate;} set{mBirthDate=value;EntityState.FieldChange("BirthDate");} } private string mBirthDate; public string Region { get{ return mRegion;} set{mRegion=value;EntityState.FieldChange("Region");} } private string mRegion; public string Remark { get{ return mRemark;} set{mRemark=value;EntityState.FieldChange("Remark");} } private string mRemark; } } |
這樣的話即使我們如何給屬性添加Attribute都不會帶來代碼上的修改,VsSingleFileGenerator只對屬性作一個模板生成其他內容搬過來就可以了:)
WPS的排版真是沒有WORD的好...估計我不會用.
【編輯推薦】
- C#在WinForm開發中Label換行方法
- C#中使用多線程訪問Winform問題解決方案
- 如何使用C#代碼實現DataTemplate