2011-01-13 82 views
6

是否有任何理由不使用代码合同来执行业务规则?代码合同是否用于安全?

想象一下,您有一个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. 
    ... 
} 

什么是这两种方法的优点和缺点?

回答

2

我认为答案是否定的。 代码合同设计用于其代码为代码为的严重错误的情况。他们应该而不是是可以从诸如不正确的用户输入中恢复的东西。

Requires<T>仅用于图书馆的公用方法,该图书馆的公用方法将由不使用代码合同的其他人使用,或者如果遗留代码需要保持兼容性,则它可能会抛出异常。

对于新代码,您应该只使用Requires而不是Requires<T>。普通Requires默认情况下会引发不可捕获的异常,以强制您处理该问题。此外,如果有人禁用代码合同运行时检查,您的所有安全性将消失!

+0

人们也可以说,在某些情况下,你给出的例子*是代码中的一个严重错误。例如,如果您正在编写的方法被埋下几层,并且所有验证都将发生在应用程序的外部层,那么这可能会被视为该方法合同的一部分。 这一切都取决于:) – porges 2011-01-14 02:32:05