MVC实用构架实战.docx
- 文档编号:6790775
- 上传时间:2023-01-10
- 格式:DOCX
- 页数:20
- 大小:78.14KB
MVC实用构架实战.docx
《MVC实用构架实战.docx》由会员分享,可在线阅读,更多相关《MVC实用构架实战.docx(20页珍藏版)》请在冰豆网上搜索。
MVC实用构架实战
MVC实用构架实战:
项目结构搭建
一、前言
在本文中,将使用代码的方式来一一解说各个层次。
由于要搭建一个基本完整的结构,可能文章会比较长。
另外,本系列主要出于实用的目的,因而并不会严格按照传统的三层那样进行非常明确的层次职能划分。
二、需求说明
在本系列中,为方便大家理解,将以一个账户管理的小系统来进行解说,具体需求如下:
1.用户信息分主要信息与扩展信息,一个用户可以有(或没有)一个用户扩展信息。
2.记录用户的登录记录,一个用户可以有多条登录记录,但登录记录所属用户唯一。
3.一个用户可以有多个角色,一个角色也可以分配给多个用户。
三、架构基础
(一)功能返回值
对于一个操作性业务功能(比如添加,修改,删除),通常我们处理返回值的做法是使用简单类型,通常会有如下几种方案:
1.直接返回void,即什么也不返回,在操作过程中抛出异常,只要没有异常抛出,就认为是操作成功了
2.返回是否操作成功的bool类型的返回值
3.返回操作变更后的新数据信息
4.返回表示各种结果的状态码的返回值
5.返回一个自定义枚举来表示操作的各种结果
6.如果要返回多个值,还要使用out来添加返回参数
这样做有什么不妥之处呢,我们来逐一分析:
1.靠抛异常的方式来终止系统的运行,异常是沿调用堆栈逐层向上抛出的,会造成很大的性能问题
2.bool值太死板,无法表示出业务操作中的各种情况
3.返回变更后的数据,还要与原始数据来判断才能得到是否操作成功
4.用状态码解决了2的问题,但各种状态码的维护成本也会非常高
5.用枚举值一定程序上解决了翻译的问题,但还是要把枚举值翻译成各种情况的文字描述
6.!
@#¥%……&
综上,我们到底需要一个怎样的业务操作结果呢?
1.要能表示操作的成功失败(废话)
2.要能快速表示各种操作场景(如参数错误,查询数据不存在,数据状态不满足操作要求等)
3.能返回附加的返回信息(如更新成功后有后续操作,需要使用更新后的新值)
4.最好在调用方能使用统一的代码进行返回值处理
5.最好能自定义返回的文字描述信息
6.最好能把返回给用户的信息与日志记录的信息分开
再综上,显然简单类型的返回值满足不了需求了,那就需要定义一个专门用来封装返回值信息的返回值类,这里定义如下:
1.///
2. /// 业务操作结果信息类,对操作结果进行封装
3. ///
4. public class OperationResult
5. {
6. #region 构造函数
7.
8. ///
9. /// 初始化一个 业务操作结果信息类 的新实例
10. ///
11. /// 业务操作结果类型
12. public OperationResult(OperationResultType resultType)
13. {
14. ResultType = resultType;
15. }
16.
17. ///
18. /// 初始化一个 定义返回消息的业务操作结果信息类 的新实例
19. ///
20. /// 业务操作结果类型
21. /// 业务返回消息
22. public OperationResult(OperationResultType resultType, string message)
23. :
this(resultType)
24. {
25. Message = message;
26. }
27.
28. ///
29. /// 初始化一个 定义返回消息与附加数据的业务操作结果信息类 的新实例
30. ///
31. /// 业务操作结果类型
32. /// 业务返回消息
33. /// 业务返回数据
34. public OperationResult(OperationResultType resultType, string message, object appendData)
35. :
this(resultType, message)
36. {
37. AppendData = appendData;
38. }
39.
40. ///
41. /// 初始化一个 定义返回消息与日志消息的业务操作结果信息类 的新实例
42. ///
43. /// 业务操作结果类型
44. /// 业务返回消息
45. /// 业务日志记录消息
46. public OperationResult(OperationResultType resultType, string message, string logMessage)
47. :
this(resultType, message)
48. {
49. LogMessage = logMessage;
50. }
51.
52. ///
53. /// 初始化一个 定义返回消息、日志消息与附加数据的业务操作结果信息类 的新实例
54. ///
55. /// 业务操作结果类型
56. /// 业务返回消息
57. /// 业务日志记录消息
58. /// 业务返回数据
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. ///
70. /// 获取或设置 操作结果类型
71. ///
72. public OperationResultType ResultType { get; set; }
73.
74. ///
75. /// 获取或设置 操作返回信息
76. ///
77. public string Message { get; set; }
78.
79. ///
80. /// 获取或设置 操作返回的日志消息,用于记录日志
81. ///
82. public string LogMessage { get; set; }
83.
84. ///
85. /// 获取或设置 操作结果附加信息
86. ///
87. public object AppendData { get; set; }
88.
89. #endregion
90. }
再定义一个表示业务操作结果的枚举,枚举项上有一个DescriptionAttribute的特性,用来作为当上面的Message为空时的返回结果描述。
1.///
2. /// 表示业务操作结果的枚举
3. ///
4. [Description("业务操作结果的枚举")]
5. public enum OperationResultType
6. {
7. ///
8. /// 操作成功
9. ///
10. [Description("操作成功。
")]
11. Success,
12.
13. ///
14. /// 操作取消或操作没引发任何变化
15. ///
16. [Description("操作没有引发任何变化,提交取消。
")]
17. NoChanged,
18.
19. ///
20. /// 参数错误
21. ///
22. [Description("参数错误。
")]
23. ParamError,
24.
25. ///
26. /// 指定参数的数据不存在
27. ///
28. [Description("指定参数的数据不存在。
")]
29. QueryNull,
30.
31. ///
32. /// 权限不足
33. ///
34. [Description("当前用户权限不足,不能继续操作。
")]
35. PurviewLack,
36.
37. ///
38. /// 非法操作
39. ///
40. [Description("非法操作。
")]
41. IllegalOperation,
42.
43. ///
44. /// 警告
45. ///
46. [Description("警告")]
47. Warning,
48.
49. ///
50. /// 操作引发错误
51. ///
52. [Description("操作引发错误。
")]
53. Error,
54. }
(二)实体基类
对于业务实体,有一些相同的且必要的信息,比如信息的创建时间,总是必要的;再比如想让数据库有一个“回收站”的功能,以给数据删除做个缓冲,或者很多数据并非想从数据库中彻底删除掉,只是暂时的“禁用”一下,添加个逻辑删除的标记也是必要的。
再有就是想给所有实体数据仓储操作来个类型限定,以防止传入了其他非实体类型。
基于以上理由,就有了下面这个实体基类:
1.///
2. /// 可持久到数据库的领域模型的基类。
3. ///
4. [Serializable]
5. public abstract class Entity
6. {
7. #region 构造函数
8.
9. ///
10. /// 数据实体基类
11. ///
12. protected Entity()
13. {
14. IsDeleted = false;
15. AddDate = DateTime.Now;
16. }
17.
18. #endregion
19.
20. #region 属性
21.
22. ///
23. /// 获取或设置 获取或设置是否禁用,逻辑上的删除,非物理删除
24. ///
25. public bool IsDeleted { get; set; }
26.
27. ///
28. /// 获取或设置 添加时间
29. ///
30. [DataType(DataType.DateTime)]
31. public DateTime AddDate { get; set; }
32.
33. ///
34. /// 获取或设置 版本控制标识,用于处理并发
35. ///
36. [ConcurrencyCheck]
37. [Timestamp]
38. public byte[] Timestamp { get; set; }
39.
40. #endregion
41. }
这里要补充一下,本来实体基类中是可以定义一个表示“实体编号”的Id属性的,但有个问题,如果定义了,就限定了Id属性的数据类型了,但实际需求中可能有些实体使用自增的int类型,有些实体使用的是易于数据合并的guid类型,因此为灵活方便,不在此限制住Id的数据类型。
四、架构分层
具体的架构分层如下图所示:
(一)核心业务层
根据需求说明 中定义的需求,简单起见,这里只实现一个简单的用户登录功能:
用户信息实体:
1.///
2. /// 实体类——用户信息
3. ///
4. [Description("用户信息")]
5. public class Member :
Entity
6. {
7. ///
8. /// 获取或设置 用户编号
9. ///
10. public int Id { get; set; }
11.
12. ///
13. /// 获取或设置 用户名
14. ///
15. [Required]
16. [StringLength(20)]
17. public string UserName { get; set; }
18.
19. ///
20. /// 获取或设置 密码
21. ///
22. [Required]
23. [StringLength(32)]
24. public string Password { get; set; }
25.
26. ///
27. /// 获取或设置 用户昵称
28. ///
29. [Required]
30. [StringLength(20)]
31. public string NickName { get; set; }
32.
33. ///
34. /// 获取或设置 用户邮箱
35. ///
36. [Required]
37. [StringLength(50)]
38. public string Email { get; set; }
39.
40. ///
41. /// 获取或设置 用户扩展信息
42. ///
43. public virtual MemberExtend Extend { get; set; }
44.
45. ///
46. /// 获取或设置 用户拥有的角色信息集合
47. ///
48. public virtual ICollection
49.
50. ///
51. /// 获取或设置 用户登录记录集合
52. ///
53. public virtual ICollection
54. }
核心业务契约:
注意接口的返回值使用了上面定义的返回值类
1.///
2. /// 账户模块核心业务契约
3. ///
4. public interface IAccountContract
5. {
6. ///
7. /// 用户登录
8. ///
9. /// 登录信息
10. ///
11. OperationResult Login(LoginInfo loginInfo);
12. }
核心业务实现:
核心业务实现类为抽象类,因没有数据访问功能,这里使用了一个Members字段来充当数据源,业务功能的实现为虚方法,必要时可以在具体的客户端(网站、桌面端,移动端)相应的派生类中进行重写。
请注意具体实现中对于返回值的处理。
这里登录只负责最核心的登录业务操作,不涉及比如Http上下文状态的操作。
1.///
2. /// 账户模块核心业务实现
3.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MVC 实用 构架 实战