微型項目實踐(6):Business層程式碼分析——實體類的建置原則

來源:互聯網
上載者:User

上一篇中,我們分析了實體類的基類Entity,這一篇中,我們就分析一下基於該類的實體類。

每一個實體類都會有兩個檔案組成,我們以BlogClass為例,該類包含兩個檔案:BlogClass.cs和BlogClass.designer.cs,這非常類似VS自己產生的程式碼,更方便的是,VS還會自動把這兩個檔案摺疊起來,。

這兩個檔案中,BlogClass.designer.cs包含所有的產生代碼:成員、屬性等,而BlogClass.cs則只包含一個類的定義,供我們填寫代碼使用。

BlogClass.designer.cs的代碼如下。

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Data.Linq;
   4:  using System.Linq;
   5:  using System.Text;
   6:   
   7:  using DongBlog.Common;
   8:   
   9:  namespace DongBlog.Business.Blogs
  10:  {
  11:      /// <summary>
  12:      /// 日誌分類
  13:      /// </summary>
  14:      public partial class BlogClass
  15:      {
  16:          #region ID和時間戳記
  17:   
  18:          private int _ID = NEW_ENTITY_ID;
  19:          private byte[] _TimeStamp = new byte[] { };
  20:   
  21:          /// <summary>
  22:          /// 取得ID
  23:          /// </summary>
  24:          public override int ID
  25:          {
  26:              get { return _ID; }
  27:          }
  28:          /// <summary>
  29:          /// 取得時間戳記
  30:          /// </summary>
  31:          public override byte[] TimeStamp
  32:          {
  33:              get { return _TimeStamp; }
  34:          }
  35:   
  36:          #endregion
  37:   
  38:          #region 成員
  39:   
  40:          private string _Name;
  41:          private string _Description;
  42:   
  43:          #endregion
  44:   
  45:          #region 屬性
  46:   
  47:          /// <summary>
  48:          /// 取得或設定名稱
  49:          /// </summary>
  50:          public string Name
  51:          {
  52:              get { return _Name; }
  53:              set { _Name = value; }
  54:          }
  55:          /// <summary>
  56:          /// 取得或設定描述
  57:          /// </summary>
  58:          public string Description
  59:          {
  60:              get { return _Description; }
  61:              set { _Description = value; }
  62:          }
  63:   
  64:          #endregion
  65:      }
  66:  }

從代碼裡可以看到,完全就是對實體XML的翻譯,需要特別指出的是,其中實現了Entity定義的ID和TimeStamp這兩個抽象屬性。

BlogClass.cs的代碼如下:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Data.Linq;
   4:  using System.Linq;
   5:  using System.Text;
   6:   
   7:  using DongBlog.Common;
   8:   
   9:  namespace DongBlog.Business.Blogs
  10:  {
  11:      /// <summary>
  12:      /// 日誌分類
  13:      /// </summary>
  14:      public partial class BlogClass : Entity<BlogClass>
  15:      {
  16:      }
  17:   
  18:      /// <summary>
  19:      /// 日誌分類的業務外觀 
  20:      /// </summary>
  21:      public static class BlogClassExtension
  22:      {
  23:      }
  24:  }
 

呃……這個更簡單了,完全就是個空的。因為它的用處就是讓我們填寫自己的代碼,現在假設我們有這麼一個功能“設定日誌分類名稱時,如果分類的描述為空白,則將分類的描述設定為其名稱”,那麼我們可以這麼幹:從BlogClass.desinger.cs檔案中,將Name屬性的定義Ctrl+X,Ctrl+V過來,然後改改,修改後的代碼如下:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Data.Linq;
   4:  using System.Linq;
   5:  using System.Text;
   6:   
   7:  using DongBlog.Common;
   8:   
   9:  namespace DongBlog.Business.Blogs
  10:  {
  11:      /// <summary>
  12:      /// 日誌分類
  13:      /// </summary>
  14:      public partial class BlogClass : Entity<BlogClass>
  15:      {
  16:          /// <summary>
  17:          /// 取得或設定名稱
  18:          /// </summary>
  19:          public string Name
  20:          {
  21:              get { return _Name; }
  22:              set
  23:              {
  24:                  _Name = value;
  25:   
  26:                  if (string.IsNullOrEmpty(_Description))
  27:                      _Description = value;
  28:              }
  29:          }
  30:      }
  31:   
  32:      /// <summary>
  33:      /// 日誌分類的業務外觀 
  34:      /// </summary>
  35:      public static class BlogClassExtension
  36:      {
  37:      }
  38:  }

這個代碼很好理解,值得一提的是,當描述實體的XML修改後,重建實體代碼時,代碼產生器會判斷BlogClass.cs中是否包含了Name屬性,如果包含了該屬性,則在BlogClass.designer.cs中,就不會再產生了。這是自己寫代碼產生而不用通用代碼產生器的好處——我的地盤我做主。:)

另外一個和實體相關的類是Extension類,顧名思義,該類包含的都是對已有類型的擴充方法,利用C#3.0的擴充方法,可以寫出非常優雅的代碼。例如,我們需要查詢某一個分類的所有Blog,給出的是該分類的ID,我們就可以在BlogExtension類中這麼寫(代碼位於\DongBlog.Business\Blogs\Blog.cs):

   1:  /// <summary>
   2:  /// 日誌的業務外觀 
   3:  /// </summary>
   4:  public static class BlogExtension
   5:  {
   6:      /// <summary>
   7:      /// 根據日誌分類取得日誌
   8:      /// </summary>
   9:      /// <param name="query">日誌查詢</param>
  10:      /// <param name="blogClassID">日誌分類ID</param>
  11:      /// <returns>該分類下的日誌</returns>
  12:      public static List<Blog> GetBlogsByClassID(this IQueryable<Blog> query, int blogClassID)
  13:      {
  14:          if (query == null)
  15:              throw new ArgumentNullException("query");
  16:   
  17:          return query
  18:              .Where(b => b.BlogClassID == blogClassID)
  19:              .OrderByDescending(b => b.UpdateDateTime)
  20:              .ToList();
  21:      }
  22:  }

上面的查詢方法使用Linq實現的,我們還順手做了一個根據更新時間的排序。有了這個方法,我們以後就可以用這樣的方式取得某一個分類的Blog:database.GetDataAccess<Blog>().GetBlogByClassID(1);該方式以後還會進一步簡化為:database.Blogs.GetBlogByClassID(1)。

最後說明一點,以上代碼都是可以測試的,因為我們所有的方法都是使用介面作為參數的,所以我們可以用腳手架(Mock類)偽實現相應的介面,以便對不同輸入和環境下的代碼進行自動化測試,具體方法就不展開了。

下一篇文章我們將分析資料訪問的設計與實現。

代碼下載

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.