Primer contacto con Code Contracts (no es un tutorial)

Hola, me llamo Pablo y hoy he sufrido mi primer contacto forzoso con Code Contracts. Lo de forzoso no es porque no me guste ese proyecto, sino porque ha sido completamente involuntario. Pero antes de nada, ¿qué es Code Contracts?

Code Contracts

Code Contracts es un proyecto de Microsoft Research para incluir en nuestro código las precondiciones y poscondiciones que deben cumplirse antes y después de su ejecución, así como los invariantes que deben cumplirse siempre. Muchos no habrán usado estas palabrejas desde que dejaron la Universidad, otros ni eso, pero al programar todos estamos asumiendo premisas que deben cumplirse (por ejemplo, que un método debe llamarse antes que otro, o que una variable tenga un rango de valores concreto), sólo que no los reflejamos en ningún sitio, sólo están en nuestra cabeza. Ahí es donde interviene Code Contracts, permitiendo poner negro sobre blanco (pixel negro sobre pixel blanco, quiero decir) esas condiciones, y además verificando que se cumplan tanto durante la ejecución de nuestro programa como de nuestros tests.

Como idea es muy interesante, y permite incrementar la calidad de nuestro código, difuminando un poco la división entre programa y tests, ya que estas comprobaciones (equivalentes a los Assert de un test) están en el propio programa. También ayuda a la legibilidad del código y a su comprensión por parte de quien venga detrás (que normalmente somos nosotros mismos dentro de un tiempo). Y su uso no es nada difícil, como muestra un botón:

public void Bind(FrameworkElement bindingObject, Func<FrameworkElement, FrameworkElement> bindingObjectParentFunc)
{
    Contract.Requires<ArgumentNullException>(bindingObject != null, "Binding object cannot be null.");
    Contract.Requires<ArgumentNullException>(bindingObjectParentFunc != null, "Binding object function cannot be null.");
…

En lugar de comprobar si nos han pasado bien los atributos con un if, lo estamos declarando usando Contract, el punto de acceso principal a la librería Code Contracts. Se entiende fácil, ¿verdad? Pues si queréis saber más, os dejo aquí una presentación de un chico que parece que sabe de esto.

¿Pero qué te ha pasado hoy?

Pues nada, que estaba tratando de localizar un error en la versión que estamos preparando para WPF de SilverDiagram, y entre cambios de código y recompilaciones de librerías me he encontrado con este error:

image

El texto es bastante más extenso, pero qué os voy a contar de esas hermosas pilas de llamadas listadas en enormes MessageBox. Todo un símbolo, y perfecto para demostrar a nuestro jefe/usuarios lo difícil que es nuestra profesión.

La cuestión es que este error viene provocado por Code Contract, porque se da una situación curiosa: Tengo dos librerías, A y B. La librería B referencia a A (pero están en soluciones distintas, así que referencia el ensamblado A.dll, pongamos).

Yo estaba probando B sin problemas, tratando de corregir el error, haciendo cambios y pruebas normalmente. Cuando identifico que el error parece estar en A, abro su solución, lo corrijo y compilo para usar esta nueva A.dll. Esta compilación no se queja.

Compilo B con la nueva A.dll y de nuevo sin problema. Pero al ejecutar, el error, ah, el error: Must use the rewriter when using Contract.Requires<TException>.

Está claro que la culpa es de Code Contracts. Echo una búsqueda rápida, y encuentro en el blog de Derik Whittacker una coincidencia. Y hace especial hincapié en que la culpa no es de B, sino del proyecto A, a pesar de no haber dado errores en su compilación. Y el motivo es sencillo: no tengo instalado Code Contracts en mi ordenador.

Instalando… y solucionado

Así que tras cerrar los Visuales Estudios, descargo e instalo desde la web de Code Contracts (hay versión comercial y académica, pero no me preguntéis sobre eso). Una vez instalado, conseguimos dos cosas:

  1. En las Propiedades de los proyectos hay una nueva pestaña Code Contracts donde podemos definir el comportamiento de esta librería en nuestro proyecto.
  2. Al volver a compilar el proyecto, ya podemos usar A.dll con normalidad en otros proyectos (si estaba bien configurada la comprobación en tiempo de ejecución de las propiedades de Code Contracts, pero esto es harina de otro costal).

Espero que esto pueda servir de ayuda para quienes sufran el mismo problema, y también para que algunos nos empecemos a introducir en Code Contracts (…por mi primero).

Un placer.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *