2011-01-13 6 views
6

¿Hay alguna razón por la cual no usaría Contratos de código para hacer cumplir las reglas comerciales?¿Se deberían usar contratos de código para la seguridad?

Imagine que tiene una clase User que representa un usuario único de un sistema y define las acciones que se pueden realizar contra otros usuarios. Se podría escribir un método ChangePassword así ...

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. 
    ... 
} 

O usted podría implementar el control de seguridad como condición previa con 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. 
    ... 
} 

¿Cuáles son las ventajas y desventajas de estos dos métodos ?

Respuesta

2

Creo que la respuesta es no. Los contratos de código están diseñados para escenarios donde su falla indica un error grave en el código. Deberían ser no ser algo que pueda recuperarse, como la entrada incorrecta del usuario.

Requires<T> está destinado a ser utilizado solo en los métodos públicos de una biblioteca que serán consumidos por otros que no utilizan Contratos de código, o si tiene código heredado que debe permanecer compatible en términos de qué excepciones puede arrojar.

Para el nuevo código, solo debe utilizar Requires, no Requires<T>. Plain Requires arroja una excepción inaptable por defecto, para forzarte a manejar el problema.

Además, si alguien desactiva la comprobación del tiempo de ejecución de Contratos de código, ¡toda su seguridad desaparecerá!

+0

También se podría argumentar que, en algunos casos, el ejemplo que usted ha dado * es * un error grave en el código. Por ejemplo, si el método que está escribiendo está enterrado varias capas hacia abajo y toda la verificación debe realizarse en la capa externa de su aplicación, esto podría considerarse parte del contrato del método. Todo depende :) – porges

+0

¡Buena respuesta! No me había dado cuenta de la naturaleza inalcanzable de 'ContractException', pero su respuesta me indicó la dirección correcta: http://www.infoq.com/articles/code-contracts-csharp ¡gracias! :) –

Cuestiones relacionadas