MVC实用构架实战Word格式文档下载.docx
《MVC实用构架实战Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《MVC实用构架实战Word格式文档下载.docx(20页珍藏版)》请在冰豆网上搜索。
综上,我们到底需要一个怎样的业务操作结果呢?
1.要能表示操作的成功失败(废话)
2.要能快速表示各种操作场景(如参数错误,查询数据不存在,数据状态不满足操作要求等)
3.能返回附加的返回信息(如更新成功后有后续操作,需要使用更新后的新值)
4.最好在调用方能使用统一的代码进行返回值处理
5.最好能自定义返回的文字描述信息
6.最好能把返回给用户的信息与日志记录的信息分开
再综上,显然简单类型的返回值满足不了需求了,那就需要定义一个专门用来封装返回值信息的返回值类,这里定义如下:
1.///
<
summary>
2.
///
业务操作结果信息类,对操作结果进行封装
3.
/summary>
4.
public
class
OperationResult
5.
{
6.
#region
构造函数
7.
8.
9.
初始化一个
业务操作结果信息类
的新实例
10.
11.
param
name="
resultType"
>
业务操作结果类型<
/param>
12.
OperationResult(OperationResultType
resultType)
13.
14.
ResultType
=
resultType;
15.
}
16.
17.
18.
定义返回消息的业务操作结果信息类
19.
20.
21.
message"
业务返回消息<
22.
resultType,
string
message)
23.
:
this(resultType)
24.
25.
Message
message;
26.
27.
28.
29.
定义返回消息与附加数据的业务操作结果信息类
30.
31.
32.
33.
appendData"
业务返回数据<
34.
message,
object
appendData)
35.
this(resultType,
36.
37.
AppendData
appendData;
38.
39.
40.
41.
定义返回消息与日志消息的业务操作结果信息类
42.
43.
44.
45.
logMessage"
业务日志记录消息<
46.
logMessage)
47.
48.
49.
LogMessage
logMessage;
50.
51.
52.
53.
定义返回消息、日志消息与附加数据的业务操作结果信息类
54.
55.
56.
57.
58.
59.
logMessage,
60.
61.
62.
63.
64.
65.
#endregion
66.
67.
属性
68.
69.
70.
获取或设置
操作结果类型
71.
72.
OperationResultType
{
get;
set;
73.
74.
75.
操作返回信息
76.
77.
78.
79.
80.
操作返回的日志消息,用于记录日志
81.
82.
83.
84.
85.
操作结果附加信息
86.
87.
88.
89.
90.
}
再定义一个表示业务操作结果的枚举,枚举项上有一个DescriptionAttribute的特性,用来作为当上面的Message为空时的返回结果描述。
表示业务操作结果的枚举
[Description("
业务操作结果的枚举"
)]
enum
OperationResultType
操作成功
操作成功。
"
Success,
操作取消或操作没引发任何变化
操作没有引发任何变化,提交取消。
NoChanged,
参数错误
参数错误。
ParamError,
指定参数的数据不存在
指定参数的数据不存在。
QueryNull,
权限不足
当前用户权限不足,不能继续操作。
PurviewLack,
非法操作
非法操作。
IllegalOperation,
警告
警告"
Warning,
操作引发错误
操作引发错误。
Error,
(二)实体基类
对于业务实体,有一些相同的且必要的信息,比如信息的创建时间,总是必要的;
再比如想让数据库有一个“回收站”的功能,以给数据删除做个缓冲,或者很多数据并非想从数据库中彻底删除掉,只是暂时的“禁用”一下,添加个逻辑删除的标记也是必要的。
再有就是想给所有实体数据仓储操作来个类型限定,以防止传入了其他非实体类型。
基于以上理由,就有了下面这个实体基类:
可持久到数据库的领域模型的基类。
[Serializable]
abstract
Entity
数据实体基类
protected
Entity()
IsDeleted
false;
AddDate
DateTime.Now;
获取或设置是否禁用,逻辑上的删除,非物理删除
bool
添加时间
[DataType(DataType.DateTime)]
DateTime
版本控制标识,用于处理并发
[ConcurrencyCheck]
[Timestamp]
byte[]
Timestamp
这里要补充一下,本来实体基类中是可以定义一个表示“实体编号”的Id属性的,但有个问题,如果定义了,就限定了Id属性的数据类型了,但实际需求中可能有些实体使用自增的int类型,有些实体使用的是易于数据合并的guid类型,因此为灵活方便,不在此限制住Id的数据类型。
四、架构分层
具体的架构分层如下图所示:
(一)核心业务层
根据需求说明
中定义的需求,简单起见,这里只实现一个简单的用户登录功能:
用户信息实体:
实体类——用户信息
用户信息"
Member
用户编号
int
Id
用户名
[Required]
[StringLength(20)]
UserName
密码
[StringLength(32)]
Password
用户昵称
NickName
用户邮箱
[StringLength(50)]
Email
用户扩展信息
virtual
MemberExtend
Extend
用户拥有的角色信息集合
ICollection<
Role>
Roles
用户登录记录集合
LoginLog>
LoginLogs
核心业务契约:
注意接口的返回值使用了上面定义的返回值类
账户模块核心业务契约
interface
IAccountContract
用户登录
loginInfo"
登录信息<
returns>
业务操作结果<
/returns>
OperationResult
Login(LoginInfo
loginInfo);
核心业务实现:
核心业务实现类为抽象类,因没有数据访问功能,这里使用了一个Members字段来充当数据源,业务功能的实现为虚方法,必要时可以在具体的客户端(网站、桌面端,移动端)相应的派生类中进行重写。
请注意具体实现中对于返回值的处理。
这里登录只负责最核心的登录业务操作,不涉及比如Http上下文状态的操作。
账户模块核心业务实现