小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

MVC實用構(gòu)架實戰(zhàn)(一)——項目結(jié)構(gòu)搭建

 小蟲子的館子 2013-07-03

〇、目錄

一、前言

二、需求說明

三、架構(gòu)基礎(chǔ)

 (一) 功能返回值

 (二) 實體基類

四、架構(gòu)分層

 (一) 核心業(yè)務(wù)層

 (二) 站點(diǎn)業(yè)務(wù)層

 (三) 站點(diǎn)展現(xiàn)層

五、源碼獲取

六、系列導(dǎo)航

一、前言

  在《上篇》中,已經(jīng)把項目整體結(jié)構(gòu)規(guī)劃做了個大概的規(guī)劃。在本文中,將使用代碼的方式來一一解說各個層次。由于要搭建一個基本完整的結(jié)構(gòu),可能文章會比較長。另外,本系列主要出于實用的目的,因而并不會嚴(yán)格按照傳統(tǒng)的三層那樣進(jìn)行非常明確的層次職能劃分。

二、需求說明

  在本系列中,為方便大家理解,將以一個賬戶管理的小系統(tǒng)來進(jìn)行解說,具體需求如下:

  1. 用戶信息分主要信息與擴(kuò)展信息,一個用戶可以有(或沒有)一個用戶擴(kuò)展信息。
  2. 記錄用戶的登錄記錄,一個用戶可以有多條登錄記錄,但登錄記錄所屬用戶唯一。
  3. 一個用戶可以有多個角色,一個角色也可以分配給多個用戶。

三、架構(gòu)基礎(chǔ)

 (一) 功能返回值

  對于一個操作性業(yè)務(wù)功能(比如添加,修改,刪除),通常我們處理返回值的做法是使用簡單類型,通常會有如下幾種方案:

  1. 直接返回void,即什么也不返回,在操作過程中拋出異常,只要沒有異常拋出,就認(rèn)為是操作成功了
  2. 返回是否操作成功的bool類型的返回值
  3. 返回操作變更后的新數(shù)據(jù)信息
  4. 返回表示各種結(jié)果的狀態(tài)碼的返回值
  5. 返回一個自定義枚舉來表示操作的各種結(jié)果
  6. 如果要返回多個值,還要使用 out 來添加返回參數(shù)

  這樣做有什么不妥之處呢,我們來逐一分析:

  1. 靠拋異常的方式來終止系統(tǒng)的運(yùn)行,異常是沿調(diào)用堆棧逐層向上拋出的,會造成很大的性能問題
  2. bool值太死板,無法表示出業(yè)務(wù)操作中的各種情況
  3. 返回變更后的數(shù)據(jù),還要與原始數(shù)據(jù)來判斷才能得到是否操作成功
  4. 用狀態(tài)碼解決了2的問題,但各種狀態(tài)碼的維護(hù)成本也會非常高
  5. 用枚舉值一定程序上解決了翻譯的問題,但還是要把枚舉值翻譯成各種情況的文字描述
  6. !@#¥%……&

  綜上,我們到底需要一個怎樣的業(yè)務(wù)操作結(jié)果呢?

  1. 要能表示操作的成功失?。◤U話)
  2. 要能快速表示各種操作場景(如參數(shù)錯誤,查詢數(shù)據(jù)不存在,數(shù)據(jù)狀態(tài)不滿足操作要求等)
  3. 能返回附加的返回信息(如更新成功后有后續(xù)操作,需要使用更新后的新值)
  4. 最好在調(diào)用方能使用統(tǒng)一的代碼進(jìn)行返回值處理
  5. 最好能自定義返回的文字描述信息
  6. 最好能把返回給用戶的信息與日志記錄的信息分開

  再綜上,顯然簡單類型的返回值滿足不了需求了,那就需要定義一個專門用來封裝返回值信息的返回值類,這里定義如下: 

復(fù)制代碼
 1     /// <summary>
 2     ///     業(yè)務(wù)操作結(jié)果信息類,對操作結(jié)果進(jìn)行封裝
 3     /// </summary>
 4     public class OperationResult
 5     {
 6         #region 構(gòu)造函數(shù)
 7 
 8         /// <summary>
 9         ///     初始化一個 業(yè)務(wù)操作結(jié)果信息類 的新實例
10         /// </summary>
11         /// <param name="resultType">業(yè)務(wù)操作結(jié)果類型</param>
12         public OperationResult(OperationResultType resultType)
13         {
14             ResultType = resultType;
15         }
16 
17         /// <summary>
18         ///     初始化一個 定義返回消息的業(yè)務(wù)操作結(jié)果信息類 的新實例
19         /// </summary>
20         /// <param name="resultType">業(yè)務(wù)操作結(jié)果類型</param>
21         /// <param name="message">業(yè)務(wù)返回消息</param>
22         public OperationResult(OperationResultType resultType, string message)
23             : this(resultType)
24         {
25             Message = message;
26         }
27 
28         /// <summary>
29         ///     初始化一個 定義返回消息與附加數(shù)據(jù)的業(yè)務(wù)操作結(jié)果信息類 的新實例
30         /// </summary>
31         /// <param name="resultType">業(yè)務(wù)操作結(jié)果類型</param>
32         /// <param name="message">業(yè)務(wù)返回消息</param>
33         /// <param name="appendData">業(yè)務(wù)返回數(shù)據(jù)</param>
34         public OperationResult(OperationResultType resultType, string message, object appendData)
35             : this(resultType, message)
36         {
37             AppendData = appendData;
38         }
39 
40         /// <summary>
41         ///     初始化一個 定義返回消息與日志消息的業(yè)務(wù)操作結(jié)果信息類 的新實例
42         /// </summary>
43         /// <param name="resultType">業(yè)務(wù)操作結(jié)果類型</param>
44         /// <param name="message">業(yè)務(wù)返回消息</param>
45         /// <param name="logMessage">業(yè)務(wù)日志記錄消息</param>
46         public OperationResult(OperationResultType resultType, string message, string logMessage)
47             : this(resultType, message)
48         {
49             LogMessage = logMessage;
50         }
51 
52         /// <summary>
53         ///     初始化一個 定義返回消息、日志消息與附加數(shù)據(jù)的業(yè)務(wù)操作結(jié)果信息類 的新實例
54         /// </summary>
55         /// <param name="resultType">業(yè)務(wù)操作結(jié)果類型</param>
56         /// <param name="message">業(yè)務(wù)返回消息</param>
57         /// <param name="logMessage">業(yè)務(wù)日志記錄消息</param>
58         /// <param name="appendData">業(yè)務(wù)返回數(shù)據(jù)</param>
59         public OperationResult(OperationResultType resultType, string message, string logMessage, object appendData)
60             : this(resultType, message, logMessage)
61         {
62             AppendData = appendData;
63         }
64 
65         #endregion
66 
67         #region 屬性
68 
69         /// <summary>
70         ///     獲取或設(shè)置 操作結(jié)果類型
71         /// </summary>
72         public OperationResultType ResultType { get; set; }
73 
74         /// <summary>
75         ///     獲取或設(shè)置 操作返回信息
76         /// </summary>
77         public string Message { get; set; }
78 
79         /// <summary>
80         ///     獲取或設(shè)置 操作返回的日志消息,用于記錄日志
81         /// </summary>
82         public string LogMessage { get; set; }
83 
84         /// <summary>
85         ///     獲取或設(shè)置 操作結(jié)果附加信息
86         /// </summary>
87         public object AppendData { get; set; }
88 
89         #endregion
90     }
復(fù)制代碼

   再定義一個表示業(yè)務(wù)操作結(jié)果的枚舉,枚舉項上有一個DescriptionAttribute的特性,用來作為當(dāng)上面的Message為空時的返回結(jié)果描述。

復(fù)制代碼
 1     /// <summary>
 2     ///     表示業(yè)務(wù)操作結(jié)果的枚舉
 3     /// </summary>
 4     [Description("業(yè)務(wù)操作結(jié)果的枚舉")]
 5     public enum OperationResultType
 6     {
 7         /// <summary>
 8         ///     操作成功
 9         /// </summary>
10         [Description("操作成功。")]
11         Success,
12 
13         /// <summary>
14         ///     操作取消或操作沒引發(fā)任何變化
15         /// </summary>
16         [Description("操作沒有引發(fā)任何變化,提交取消。")]
17         NoChanged,
18 
19         /// <summary>
20         ///     參數(shù)錯誤
21         /// </summary>
22         [Description("參數(shù)錯誤。")]
23         ParamError,
24 
25         /// <summary>
26         ///     指定參數(shù)的數(shù)據(jù)不存在
27         /// </summary>
28         [Description("指定參數(shù)的數(shù)據(jù)不存在。")]
29         QueryNull,
30 
31         /// <summary>
32         ///     權(quán)限不足
33         /// </summary>
34         [Description("當(dāng)前用戶權(quán)限不足,不能繼續(xù)操作。")]
35         PurviewLack,
36 
37         /// <summary>
38         ///     非法操作
39         /// </summary>
40         [Description("非法操作。")]
41         IllegalOperation,
42 
43         /// <summary>
44         ///     警告
45         /// </summary>
46         [Description("警告")]
47         Warning,
48 
49         /// <summary>
50         ///     操作引發(fā)錯誤
51         /// </summary>
52         [Description("操作引發(fā)錯誤。")]
53         Error,
54     }
復(fù)制代碼

 (二) 實體基類

  對于業(yè)務(wù)實體,有一些相同的且必要的信息,比如信息的創(chuàng)建時間,總是必要的;再比如想讓數(shù)據(jù)庫有一個“回收站”的功能,以給數(shù)據(jù)刪除做個緩沖,或者很多數(shù)據(jù)并非想從數(shù)據(jù)庫中徹底刪除掉,只是暫時的“禁用”一下,添加個邏輯刪除的標(biāo)記也是必要的。再有就是想給所有實體數(shù)據(jù)倉儲操作來個類型限定,以防止傳入了其他非實體類型?;谝陨侠碛?,就有了下面這個實體基類:

復(fù)制代碼
 1     /// <summary>
 2     ///     可持久到數(shù)據(jù)庫的領(lǐng)域模型的基類。
 3     /// </summary>
 4     [Serializable]
 5     public abstract class Entity
 6     {
 7         #region 構(gòu)造函數(shù)
 8 
 9         /// <summary>
10         ///     數(shù)據(jù)實體基類
11         /// </summary>
12         protected Entity()
13         {
14             IsDeleted = false;
15             AddDate = DateTime.Now;
16         }
17 
18         #endregion
19 
20         #region 屬性
21 
22         /// <summary>
23         ///     獲取或設(shè)置 獲取或設(shè)置是否禁用,邏輯上的刪除,非物理刪除
24         /// </summary>
25         public bool IsDeleted { get; set; }
26 
27         /// <summary>
28         ///     獲取或設(shè)置 添加時間
29         /// </summary>
30         [DataType(DataType.DateTime)]
31         public DateTime AddDate { get; set; }
32 
33         /// <summary>
34         ///     獲取或設(shè)置 版本控制標(biāo)識,用于處理并發(fā)
35         /// </summary>
36         [ConcurrencyCheck]
37         [Timestamp]
38         public byte[] Timestamp { get; set; }
39 
40         #endregion
41     }
復(fù)制代碼

   這里要補(bǔ)充一下,本來實體基類中是可以定義一個表示“實體編號”的Id屬性的,但有個問題,如果定義了,就限定了Id屬性的數(shù)據(jù)類型了,但實際需求中可能有些實體使用自增的int類型,有些實體使用的是易于數(shù)據(jù)合并的guid類型,因此為靈活方便,不在此限制住 Id的數(shù)據(jù)類型。

四、架構(gòu)分層

  具體的架構(gòu)分層如下圖所示:

 (一) 核心業(yè)務(wù)層

   根據(jù) 需求說明 中定義的需求,簡單起見,這里只實現(xiàn)一個簡單的用戶登錄功能:

  用戶信息實體:

復(fù)制代碼
 1     /// <summary>
 2     ///     實體類——用戶信息
 3     /// </summary>
 4     [Description("用戶信息")]
 5     public class Member : Entity
 6     {
 7         /// <summary>
 8         /// 獲取或設(shè)置 用戶編號
 9         /// </summary>
10         public int Id { get; set; }
11 
12         /// <summary>
13         /// 獲取或設(shè)置 用戶名
14         /// </summary>
15         [Required]
16         [StringLength(20)]
17         public string UserName { get; set; }
18 
19         /// <summary>
20         /// 獲取或設(shè)置 密碼
21         /// </summary>
22         [Required]
23         [StringLength(32)]
24         public string Password { get; set; }
25 
26         /// <summary>
27         /// 獲取或設(shè)置 用戶昵稱
28         /// </summary>
29         [Required]
30         [StringLength(20)]
31         public string NickName { get; set; }
32 
33         /// <summary>
34         /// 獲取或設(shè)置 用戶郵箱
35         /// </summary>
36         [Required]
37         [StringLength(50)]
38         public string Email { get; set; }
39 
40         /// <summary>
41         /// 獲取或設(shè)置 用戶擴(kuò)展信息
42         /// </summary>
43         public virtual MemberExtend Extend { get; set; }
44 
45         /// <summary>
46         /// 獲取或設(shè)置 用戶擁有的角色信息集合
47         /// </summary>
48         public virtual ICollection<Role> Roles { get; set; }
49 
50         /// <summary>
51         /// 獲取或設(shè)置 用戶登錄記錄集合
52         /// </summary>
53         public virtual ICollection<LoginLog> LoginLogs { get; set; }
54     }
復(fù)制代碼

  核心業(yè)務(wù)契約:注意接口的返回值使用了上面定義的返回值類

復(fù)制代碼
 1     /// <summary>
 2     ///     賬戶模塊核心業(yè)務(wù)契約
 3     /// </summary>
 4     public interface IAccountContract
 5     {
 6         /// <summary>
 7         /// 用戶登錄
 8         /// </summary>
 9         /// <param name="loginInfo">登錄信息</param>
10         /// <returns>業(yè)務(wù)操作結(jié)果</returns>
11         OperationResult Login(LoginInfo loginInfo);
12     }
復(fù)制代碼

   核心業(yè)務(wù)實現(xiàn):核心業(yè)務(wù)實現(xiàn)類為抽象類,因沒有數(shù)據(jù)訪問功能,這里使用了一個Members字段來充當(dāng)數(shù)據(jù)源,業(yè)務(wù)功能的實現(xiàn)為虛方法,必要時可以在具體的客戶端(網(wǎng)站、桌面端,移動端)相應(yīng)的派生類中進(jìn)行重寫。請注意具體實現(xiàn)中對于返回值的處理。這里登錄只負(fù)責(zé)最核心的登錄業(yè)務(wù)操作,不涉及比如Http上下文狀態(tài)的操作。

復(fù)制代碼
 1     /// <summary>
 2     ///     賬戶模塊核心業(yè)務(wù)實現(xiàn)
 3     /// </summary>
 4     public abstract class AccountService : IAccountContract
 5     {
 6         private static readonly Member[] Members = new[]
 7         {
 8             new Member { UserName = "admin", Password = "123456", Email = "admin@gmfcn.net", NickName = "管理員" },
 9             new Member { UserName = "gmfcn", Password = "123456", Email = "mf.guo@qq.com", NickName = "郭明鋒" }
10         };
11 
12         private static readonly List<LoginLog> LoginLogs = new List<LoginLog>();
13 
14         /// <summary>
15         /// 用戶登錄
16         /// </summary>
17         /// <param name="loginInfo">登錄信息</param>
18         /// <returns>業(yè)務(wù)操作結(jié)果</returns>
19         public virtual OperationResult Login(LoginInfo loginInfo)
20         {
21             PublicHelper.CheckArgument(loginInfo, "loginInfo");
22             Member member = Members.SingleOrDefault(m => m.UserName == loginInfo.Access || m.Email == loginInfo.Access);
23             if (member == null)
24             {
25                 return new OperationResult(OperationResultType.QueryNull, "指定賬號的用戶不存在。");
26             }
27             if (member.Password != loginInfo.Password)
28             {
29                 return new OperationResult(OperationResultType.Warning, "登錄密碼不正確。");
30             }
31             LoginLog loginLog = new LoginLog { IpAddress = loginInfo.IpAddress, Member = member };
32             LoginLogs.Add(loginLog);
33             return new OperationResult(OperationResultType.Success, "登錄成功。", member);
34         }
35     }
復(fù)制代碼

(二) 站點(diǎn)業(yè)務(wù)層

  站點(diǎn)業(yè)務(wù)契約:站點(diǎn)業(yè)務(wù)契約繼承核心業(yè)務(wù)契約,即可擁有核心層定義的業(yè)務(wù)功能。站點(diǎn)登錄驗證使用了Forms的Cookie驗證,這里的退出不涉及核心層的操作,因而核心層沒有退出功能

復(fù)制代碼
 1     /// <summary>
 2     ///     賬戶模塊站點(diǎn)業(yè)務(wù)契約
 3     /// </summary>
 4     public interface IAccountSiteContract : IAccountContract
 5     {
 6         /// <summary>
 7         ///     用戶登錄
 8         /// </summary>
 9         /// <param name="model">登錄模型信息</param>
10         /// <returns>業(yè)務(wù)操作結(jié)果</returns>
11         OperationResult Login(LoginModel model);
12 
13         /// <summary>
14         ///     用戶退出
15         /// </summary>
16         void Logout();
17     }
復(fù)制代碼

  站點(diǎn)業(yè)務(wù)實現(xiàn):站點(diǎn)業(yè)務(wù)實現(xiàn)繼承核心業(yè)務(wù)實現(xiàn)與站點(diǎn)業(yè)務(wù)契約,負(fù)責(zé)把從UI中接收到的視圖模型信息轉(zhuǎn)換為符合核心層定義的參數(shù),并處理與網(wǎng)站狀態(tài)相關(guān)的Session,Cookie等Http相關(guān)業(yè)務(wù)。

  在這里需要注意的是,目前的項目中并沒有加入IOC組件來對層與層之間進(jìn)行解耦,在上層調(diào)用下層的時候,我們?nèi)匀灰匀缦路绞絹磉M(jìn)行實例化:

1 IAccountSiteContract accountContract = new AccountSiteService();

  這會造成層與層之間緊耦合,在后面的文章中,會加入.NET自帶的MEF組件進(jìn)行層之間的解耦,到時層對象實現(xiàn)化的工作將由MEF來完成,就需要把 AccountSiteService 類的可訪問性由 public 修改為 internal,以防止出現(xiàn)上面的實例化代碼出現(xiàn)。

復(fù)制代碼
 1     /// <summary>
 2     ///     賬戶模塊站點(diǎn)業(yè)務(wù)實現(xiàn)
 3     /// </summary>
 4     public class AccountSiteService : AccountService, IAccountSiteContract
 5     {
 6         /// <summary>
 7         ///     用戶登錄
 8         /// </summary>
 9         /// <param name="model">登錄模型信息</param>
10         /// <returns>業(yè)務(wù)操作結(jié)果</returns>
11         public OperationResult Login(LoginModel model)
12         {
13             PublicHelper.CheckArgument(model, "model");
14             LoginInfo loginInfo = new LoginInfo
15             {
16                 Access = model.Account,
17                 Password = model.Password,
18                 IpAddress = HttpContext.Current.Request.UserHostAddress
19             };
20             OperationResult result = base.Login(loginInfo);
21             if (result.ResultType == OperationResultType.Success)
22             {
23                 Member member = (Member)result.AppendData;
24                 DateTime expiration = model.IsRememberLogin
25                     ? DateTime.Now.AddDays(7)
26                     : DateTime.Now.Add(FormsAuthentication.Timeout);
27                 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, member.UserName, DateTime.Now, expiration,
28                     true, member.NickName, FormsAuthentication.FormsCookiePath);
29                 HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket));
30                 if (model.IsRememberLogin)
31                 {
32                     cookie.Expires = DateTime.Now.AddDays(7);
33                 }
34                 HttpContext.Current.Response.Cookies.Set(cookie);
35                 result.AppendData = null;
36             }
37             return result;
38         }
39 
40         /// <summary>
41         ///     用戶退出
42         /// </summary>
43         public void Logout()
44         {
45             FormsAuthentication.SignOut();
46         }
47     }
復(fù)制代碼

(三) 站點(diǎn)展現(xiàn)層

  MVC控制器:Action提供統(tǒng)一風(fēng)格的代碼來對業(yè)務(wù)操作結(jié)果OperationResult進(jìn)行處理

復(fù)制代碼
 1     public class AccountController : Controller
 2     {
 3         public AccountController()
 4         {
 5             AccountContract = new AccountSiteService();
 6         }
 7 
 8         #region 屬性
 9 
10         public IAccountSiteContract AccountContract { get; set; }
11 
12         #endregion
13 
14         #region 視圖功能
15 
16         public ActionResult Login()
17         {
18             string returnUrl = Request.Params["returnUrl"];
19             returnUrl = returnUrl ?? Url.Action("Index", "Home", new { area = "" });
20             LoginModel model = new LoginModel
21             {
22                 ReturnUrl = returnUrl
23             };
24             return View(model);
25         }
26 
27         [HttpPost]
28         public ActionResult Login(LoginModel model)
29         {
30             try
31             {
32                 OperationResult result = AccountContract.Login(model);
33                 string msg = result.Message ?? result.ResultType.ToDescription();
34                 if (result.ResultType == OperationResultType.Success)
35                 {
36                     return Redirect(model.ReturnUrl);
37                 }
38                 ModelState.AddModelError("", msg);
39                 return View(model);
40             }
41             catch (Exception e)
42             {
43                 ModelState.AddModelError("", e.Message);
44                 return View(model);
45             }
46         }
47 
48         public ActionResult Logout( )
49         {
50             string returnUrl = Request.Params["returnUrl"];
51             returnUrl = returnUrl ?? Url.Action("Index", "Home", new { area = "" });
52             if (User.Identity.IsAuthenticated)
53             {
54                 AccountContract.Logout();
55             }
56             return Redirect(returnUrl);
57         }
58 
59         #endregion
60     }
復(fù)制代碼

   MVC 視圖:

復(fù)制代碼
@model GMF.Demo.Site.Models.LoginModel
@{
    ViewBag.Title = "Login";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Login</h2>
@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>LoginModel</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.Account)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Account)
            @Html.ValidationMessageFor(model => model.Account)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.Password)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Password)
            @Html.ValidationMessageFor(model => model.Password)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.IsRememberLogin)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.IsRememberLogin)
            @Html.ValidationMessageFor(model => model.IsRememberLogin)
        </div>
        @Html.HiddenFor(m => m.ReturnUrl)
        <p>
            <input type="submit" value="登錄" />
        </p>
    </fieldset>
}
<div>
    @Html.ActionLink("Back to List", "Index", "Home")
</div>
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}
復(fù)制代碼

  至此,整個項目構(gòu)架搭建完成,運(yùn)行結(jié)果如下:
  

在本篇中,網(wǎng)站的Controller是依賴于站點(diǎn)業(yè)務(wù)實現(xiàn)與核心業(yè)務(wù)實現(xiàn)的,在下一篇中,將使用.net 4.0自帶的MEF作為IOC對層與層之間的依賴進(jìn)行解耦。

五、源碼下載

  GMFrameworkForBlog.zip

  為了讓大家能第一時間獲取到本架構(gòu)的最新代碼,也為了方便我對代碼的管理,本系列的源碼已加入微軟的開源項目網(wǎng)站 http://www.,地址為:

  https://gmframework./

  可以通過下列途徑獲取到最新代碼:

  • 如果你是本項目的參與者,可以通過VS自帶的團(tuán)隊TFS直接連接到 https://tfs.:443/tfs/TFS17 獲取最新代碼
  • 如果你安裝有SVN客戶端,可以連接到 https://gmframework.svn./svn 獲取最新代碼
  • 如果以上條件都不滿足,你可以進(jìn)入頁面 https://gmframework./SourceControl/latest 查看最新代碼,也可以點(diǎn)擊頁面上的 Download 鏈接進(jìn)行壓縮包的下載,你還可以點(diǎn)擊頁面上的 History 鏈接獲取到歷史版本的源代碼
  • 如果你想和大家一直學(xué)習(xí)MVC,學(xué)習(xí)EF,歡迎加入群:5008599(群發(fā)言僅限技術(shù)討論,拒絕閑聊,拒絕醬油,拒絕廣告)
  • 如果你想與我共同來完成這個開源項目,可以隨時聯(lián)系我。

系列導(dǎo)航

  1. MVC實用架構(gòu)設(shè)計(〇)——總體設(shè)計
  2. MVC實用架構(gòu)設(shè)計(一)——項目結(jié)構(gòu)搭建
  3. MVC實用架構(gòu)設(shè)計(二)——使用MEF實用IOC
  4. MVC實用架構(gòu)設(shè)計(三)——EF-Code First(1):Repository,UnitOfWork,DbContext
  5. MVC實用架構(gòu)設(shè)計(三)——EF-Code First(2):實體映射、數(shù)據(jù)遷移,重構(gòu)
  6. MVC實用架構(gòu)設(shè)計(三)——EF-Code First(3):使用T4模板生成相似代碼
  7. MVC實用架構(gòu)設(shè)計(三)——EF-Code First(4):數(shù)據(jù)查詢
  8. MVC實用架構(gòu)設(shè)計(三)——EF-Code First(5):二級緩存
  9. MVC實體架構(gòu)設(shè)計(四)——日志記錄
  10. 未完待續(xù)。。。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約