您是否有任何理由不使用代码合同来执行业务规则?
假设您有一个User
类,它代表系统的单个用户,并定义可以对其他用户执行的操作。您可以像这样写一个ChangePassword
方法......
public void ChangePassword(User requestingUser, string newPassword)
{
Contract.Requires<ArgumentNullException>(requestingUser);
Contract.Requires<ArgumentNullException>(newPassword);
// Users can always change their own password, but they must be an
// administrator to change someone else's.
if (requestingUser.UserId != this.UserId &&
!requestingUser.IsInRole("Administrator"))
throw new SecurityException("You don't have permission to do that.");
// Change the password.
...
}
或者您可以将安全检查作为Contract.Requires
...
public void ChangePassword(User requestingUser, string newPassword)
{
Contract.Requires<ArgumentNullException>(requestingUser != null);
Contract.Requires<ArgumentNullException>(newPassword != null);
// Users can always change their own password, but they must be an
// administrator to change someone else's.
Contract.Requires<SecurityException>(
requestingUser.UserId == this.UserId ||
!requestingUser.IsInRole("Administrator"),
"You don't have permission to do that.");
// Change the password.
...
}
这两种方法有哪些优点和缺点?
答案 0 :(得分:2)
我认为答案是肯定的。 代码约定是针对其失败表明代码中的严重错误的情况而设计的。他们应该不是可以从错误的用户输入中恢复的东西。
Requires<T>
仅适用于未使用代码约定的其他人使用的库的公共方法,或者如果您有遗留代码需要保持兼容的例外情况可以扔。
对于新代码,您应该只使用Requires
,而不是Requires<T>
。普通Requires
默认会抛出一个无法捕获的异常,迫使您处理该问题。
此外,如果某人禁用了Code Contracts运行时检查,那么您的所有安全性都将消失!