Gerardo Contijoch

Experiencias del día a día trabajando con .NET – ASP.NET, C#, ASP.NET MVC y demas…

Archive for 30 diciembre 2008

Error de compilación CS0016 en site corriendo en IIS

Posted by Gerardo Contijoch en diciembre 30, 2008

Hoy por primera vez necesite levantar un site en II7 sobre Windows Vista y me encontré con un viejo problema: el error de compilación CS0016, que se presenta con el siguiente mensaje:

Compiler Error Message: CS0016: Could not write to output file ‘c:\Windows\Microsoft.NET\Framework\[version de framework]\Temporary ASP.NET Files\root\fc8191ba\bb891bec\App_global.asax.pwk2xkjx.dll’ — ‘Access is denied. ‘

El nombre del archivo puede ser diferente ya que es generado dinámicamente al azar.

Este problema no es nuevo, ya que con otras versiones de Windows también sucede lo mismo y se debe a que el usuario con el cual estamos ejecutando el proceso de compilación no tiene permisos de escritura sobre el path indicado ni sobre el directorio temporal de Windows (esto último no lo dice en ningún lado, pero es así). Este usuario es el usuario configurado en el Application Pool asociado a nuestro site. Por defecto es el usuario NETWORK SERVICE, por lo que el problema se soluciona simplemente dándole permisos de modificación y escritura (no es necesario Full Control como figura en muchos lugares) a ese usuario sobre los paths arriba indicados.

Actualización 10/06/2009:

Luego de investigar un poco más sobre este tema, encontré aquí que el problema también puede ser causado el antivirus McAfee. Resulta que este antivirus tiene una característica que bloquea la ejecución de scripts dentro de carpetas temporales y esto puede estar interfiriendo. Para desactivar esta característica sólo tienen que seguir las instrucciones aquí expuestas.

Otra posibilidad es que el directorio de archivos temporales de Windows no este registrado entre las variables de entorno de sistema (algo raro, pero puede pasar si andamos tocando lo que no debemos). Para verificar esto, tenemos que ir a System Properties (o propiedades de Mi PC) y ahi seleccionar el tab Advanced, al final de todo hay un boton llamado Environment variables…, el cual clickeamos y en la sección System variables de la ventana que se abre tendremos que encontrar a TEMP y a TMP. Si no se encuentra alguno de los dos, entonces hay que agregarlos y asociarles como valor el path de los archivos temporales (tipicamente %Systemroot%\Temp). Luego de hacer esto, reinician IIS y listo. Tengan en cuenta que si no estan seguros de lo que hacen es mejor no tocar estos settings porque pueden dejar de funcionar muchas cosas si hacen algo mal.

Referencias:

¡Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in ASP.NET, Desarrollo Web | Etiquetado: , | 16 Comments »

Personalizar la lista de links favoritos de los diálogos de Windows Vista

Posted by Gerardo Contijoch en diciembre 30, 2008

Les voy a comentar de un pequeño truco que puede resultar muy útil para los que trabajamos sobre Windows Vista.

Yo tengo la costumbre de guardar mis proyectos en una carpeta llamada Proyectos y no en el path por defecto dentro de Documents. Esto trae como consecuencia que cuando quiero abrir un proyecto que no se encuentre entre los recientemente abiertos (conocidos como MRU List), tenga que navegar con Open File Dialog hasta la ubicación de mis proyectos. Hice eso durante un tiempo, pero me canse de tanto click y me puse a buscar una manera de personalizar la lista de links favoritos de los Open File Dialogs. Resulta que hay una manera sencillísima de hacerlo y consiste simplemente en crear un acceso directo a la carpeta que deseemos dentro del path %USERPROFILE%\Links. Todos los accesos directos que se encuentren allí van a formar parte de la lista de links favoritos de los diálogos de Windows Vista.

Les dejo el link al artículo de donde saqué esta info.

¡Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in Windows Vista | Etiquetado: | Leave a Comment »

Sys.WebForms.PageRequestManagerParserErrorException al hacer un postback parcial

Posted by Gerardo Contijoch en diciembre 26, 2008

Hace unos días me encontré con otro problema bastante molesto en ASP.NET AJAX al cual no le encontré solución. Se presenta cuando se hace un postback parcial y se muestra un error como el siguiente:

Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled.

Details: Error parsing near ‘<!DOCTYPE html P’.

(Noten que el nodo <!DOCTYPE> parece estar truncado en la respuesta)

Luego de buscar un rato, me encontré con este post de Eilon Lipton (¡el creador de este error!) donde explica porque sucede y como se puede evitar.

Cuando uno hace un postback parcial la respuesta viene en un formato especial el cual es interpretado por los scripts del lado del cliente de ASP.NET AJAX. Si nosotros durante el procesamiento del postback modificamos la respuesta, entonces los scripts van a ser incapaces de procesarla, produciendo este mensaje de error.

Para evitarlo hay que tener presente los siguientes puntos:

Nunca ejecutar Response.Write(“…”); durante un postback asincrónico.

Esto se debe a que al escribir directamente sobre la respuesta, estamos modificándola sin que los objetos encargados de procesarla lo sepan y por lo tanto, no pueden prever esos cambios.

Uso de filtros de las respuestas y HttpModules.

Al igual que con el punto anterior, si modificamos la respuesta de alguna manera, vamos a estar provocando este error seguro.

No habilitar el Trace.

Cuando uno habilita el trace en las paginas, básicamente lo que se esta haciendo es una serie de Response.Write(“…”); con la información de tracing.

Llamadas a Server.Transfer();

Cuando uno ejecuta Server.Transfer(), la respuesta deja de ser la respuesta que espera el objeto que provoca el postback asincrónico y pasa a ser el HTML generado por la página a la cual hicimos el transfer. Obviamente, esto va a interferir con el procesamiento de la respuesta (¡ya que la esta sería una pagina completa totalmente diferente a la respuesta esperada!).

En mi caso particular, no estaba haciendo nada de lo mencionado arriba, sino que estaba agregando una cookie a la respuesta, lo cual evidentemente la modifica, así que podemos agregar a la lista:

No agregar cookies a la respuesta de un postback asincrónico.

Al agregar las cookies a la respuesta, la estamos modificando (ya que enviamos la información de la cookie), por lo que hay que evitar hacerlo.

Entonces, ¿cómo se soluciona el problema cuando no podemos dejar de usar cookies o HttpModules? La solución que encontré yo fue muy simple: reescribí la página en cuestión y saque todo lo referente a ASP.NET AJAX. Todo funcionó de maravillas con un postback clásico.

¡Nos vemos en el próximo post!

PD: Si realmente necesitan modificar la respuesta en una llamada parcial, este post puede serles utiles, yo no lo probe, pero parece que funciona…

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in ASP.NET, Desarrollo Web | Etiquetado: , , | 3 Comments »

Acceder directamente al test que falló en MSTest

Posted by Gerardo Contijoch en diciembre 16, 2008

Una de las cosas que más me molesta de ejecutar los tests dentro de Visual Studio (MSTest), es que para llegar al código de un test que falló, tengo que acceder a la ventana de resultados del test, y recién ahí hacer click en el link al archivo (que nos lleva directamente a la línea que falló).

Afortundamente, Simone Chiaretta encontró la solución al problema, ¡y la encontró dentro del propio Visual Studio!

Les dejo el link.

¡Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in Testing, Visual Studio | Etiquetado: , , , | Leave a Comment »

Sys.ScriptLoadFailedException al intentar cargar un script dinámicamente con ScriptManager

Posted by Gerardo Contijoch en diciembre 16, 2008

Hoy estaba trabajando en un site que usa ASP.NET AJAX y me encontré con el siguiente error:

Sys.ScriptLoadFailedException: The script ‘http://localhost:49573/scripts/Script.js&#8217; could not be loaded.

Ese es un script que yo cargo dinámicamente mediante el ScriptManager de la siguiente manera:

ScriptManager.RegisterClientScriptInclude(pagina, typeof(Page), "miScript", "scripts/Script.js");

Busqué códigos de ejemplos en internet y todos eran iguales al mío, no encontraba el error hasta que me topé con este post de Bill Robertson.

Resulta que ASP.NET AJAX carga los scritps registrados de esta manera de forma asincrónica y es necesario notificar la finalización de la carga de cada script para que todo funcione como debería. Para realizar la notificación simplemente hay que agregar el siguiente código al final del archivo js al que hagamos referencia:

   1: if(typeof(Sys) != "undefined" && typeof(Sys.Application) != "undefined") {
   2:    Sys.Application.notifyScriptLoaded();
   3: }

La validación de la línea 1 no es necesaria en realidad, pero si usamos este archivo en un site donde no se usa ASP.NET AJAX, la línea 2 va a fallar (debido a que puede no existir el objeto Sys).

Una vez hecho eso, el site comenzó a funcionar como siempre y el script se cargó correctamente.

¡Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in ASP.NET, Desarrollo Web, Javascript | Etiquetado: , , , | 2 Comments »

Cómo actualizar el contenido de una carpeta remota en Finder (Mac OS X Tiger)

Posted by Gerardo Contijoch en diciembre 13, 2008

Como programador .NET que soy, yo trabajo sobre un equipo con Windows Vista (una PC), pero cuestiones como navegación, música, videos o cualquier otra tarea que no sea programar la hago sobre un MacBook Pro (con Mac OS X 10.4). Debido a esto, muchas veces preciso pasar archivos desde la PC a la Mac con lo cual no tengo problemas, pero hay un pequeño detalle que me resulta muy molesto en Finder: No se actualiza automáticamente el contenido de las carpetas remotas (no se si también ocurre con carpetas remotas en otros equipos de Apple, o solo con las de Windows).

Según leí, normalmente las aplicaciones que funcionan sobre Mac OS envían notificaciones a Finder sobre la modificación de carpetas (es por eso que la actualización de carpetas locales funciona sin problemas), pero cuando trabajamos en red, en realidad no hay manera de que una aplicación en Windows le notifique a Mac OS que el contenido de una carpeta se modificó y es por ello que no se refrescan automáticamente (aparentemente eso se arregló en Mac OX 10.5).

Buscando en Internet me encontré con esta herramienta llamada Finder Refresh que nos soluciona el problema (aunque no automáticamente). Pueden encontrar las instrucciones en español en esta página.

¡Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in Apple | Etiquetado: , | Leave a Comment »

Inversión de control e inyección de dependencias

Posted by Gerardo Contijoch en diciembre 6, 2008

La inversión de control (IoC -Inversion of control-, de ahora en adelante) es un principio en el cual se basan muchos de los patrones que vemos día a día. Consiste en invertir el flujo de ejecución de modo que nuestro código sea invocado, en vez de nosotros ser los invocadores (lo que implicaría que nosotros dejaríamos de tener control sobre el flujo de ejecución). El ejemplo más famoso (o por lo menos uno de los más usados) de esto es uno presentado por Martin Fowler en su artículo ‘Inversion of control‘. En el artículo él compara como uno interactúa con una aplicación en modo texto y como lo hace con una con ventanas.

Veamos este ejemplo, adaptado a C#:

   1: public static void Main(string[] args){
   2:     string nombre;
   3:     string busqueda;
   4:
   5:     Console.WriteLine("¿Cuál es su nombre?:");
   6:     nombre = Console.ReadLine();
   7:
   8:     ProcesarNombre(nombre);
   9:
  10:     Console.WriteLine("¿Qué busca?:");
  11:     busqueda = Console.ReadLine();
  12:
  13:     ProcesarBusqueda(busqueda);
  14:
  15:     /*...*/
  16: }

Como se puede apreciar, nuestro código es el que tiene el control sobre el flujo de ejecución. Nuestro código decide cuando se realiza el procesamiento y cuando las preguntas.

Veamos ahora como sería la misma aplicación, pero en un sistema de ventanas (código simplificado):

   1: public class Formulario : Form {
   2:
   3:     private System.Windows.Forms.Label lblNombre = new System.Windows.Forms.Label();
   4:     private System.Windows.Forms.Label lblBusqueda = new System.Windows.Forms.Label();
   5:     private System.Windows.Forms.TextBox txtNombre = new System.Windows.Forms.TextBox();
   6:     private System.Windows.Forms.TextBox txtBusqueda = new System.Windows.Forms.TextBox();
   7:
   8:     public Formulario() {
   9:         InitializeComponent();
  10:     }
  11:
  12:     private void InitializeComponent() {
  13:         this.lblNombre.Text = "¿Cuál es su nombre?:";
  14:         this.lblBusqueda.Text = "¿Qué busca?:";
  15:
  16:         this.txtNombre.LostFocus += new System.EventHandler(txtNombre_LostFocus);
  17:         this.txtBusqueda.LostFocus += new System.EventHandler(txtBusqueda_LostFocus);
  18:     }
  19:
  20:     private void txtNombre_LostFocus(object sender, EventArgs e) {
  21:         ProcesarNombre(this.txtNombre.Text);
  22:     }
  23:
  24:     private void txtBusqueda_LostFocus(object sender, System.EventArgs e) {
  25:         ProcesarBusqueda(this.txtBusqueda.Text);
  26:     }
  27:     /*...*/
  28: }

En este caso, nosotros no somos los que tenemos control sobre el flujo de ejecución, sino el propio formulario, y es él el que decide cuando se procesan los datos.

Hay distintas formas de IoC. Una de ellas, como acabamos de ver, es el patrón Listener u Observer, en donde se pasa el control de la ejecución de ciertas tareas a otro componente. Otra forma común de IoC es la aplicación de ciertos patrones de construcción, como pueden ser Factoría, Factoría abstracta y Builder. En estos casos, se pasa el control de la construcción de objetos a otros componentes que nos resuelven la instanciación (o recuperación) de los distintos objetos de los cuales nuestro código/módulo/componente depende. Particularmente quiero hacer hincapié en otra de las formas de IoC, llamada Inyección de dependencias.

Inyección de dependencias

La inyección de dependencias (DI – Dependency Injection-, de ahora en adelante) es un principio de diseño muy utilizado últimamente, debido principalmente a la ‘gran movida’ que esta teniendo el unit testing con frameworks para mocking. El testing con mocks depende mucho del uso de este patrón ya que se basa en la inyección de dependencias fabricadas o personalizadas específicamente para cada test. Pero ese es otro tema, ahora me voy a concentrar en explicar un poco que es esto de DI.

Como dije, DI es básicamente una forma de IoC, en donde lo que se invierte es la lógica de recuperación de las dependencias de modo que los componentes dependientes no tengan ni siquiera que molestarse en buscar las ya que las mismas les son provistas.

Para entender de que trata esto, tomemos como ejemplo un sistema de compras online. Este sistema entre otras cosas tendría un carrito donde se van guardando los productos que se van comprando. Su uso básicamente seria el siguiente:

   1: public class WebSite {
   2:     /* ... */
   3:     public void Comprar() {
   4:
   5:         var p = new Producto() { Descripcion = "Mouse", Precio = 10 };
   6:
   7:         var carrito = new CarritoDeCompras();
   8:
   9:         carrito.AgregarNuevoItem(p);
  10:     }
  11:     /* ... */
  12: }

Siendo el código del carrito el siguiente:

   1: public class CarritoDeCompras {
   2:         /* ... */
   3:     public void AgregarNuevoItem(Producto p) {
   4:
   5:         // Validamos el producto antes de ingresarlo
   6:
   7:         if (p.Descripcion == "") {
   8:             // Notificar de error en la descripcion
   9:         }
  10:
  11:         if (p.Precio <= 0) {
  12:             // Notificar precio inválido
  13:         }
  14:
  15:         // Agregar el producto a la lista de compras
  16:         /* ... */
  17:     }
  18:
  19:     /* ... */
  20: }

Como se puede apreciar, es el propio carrito el que realiza la validación del producto antes de procesarlo. Esto no es muy deseable ya que hace que el sistema de validaciones sea muy poco flexible y toda la responsabilidad de validar los productos caiga en el propio carrito.

Para ayudarnos, vamos a hacer uso de una clase helper para validar productos, quedando el código del nuevo carrito así:

   1: public class ValidadorDeProductos {
   2:
   3:     public bool ValidarProducto(Producto p) {
   4:
   5:         if (p.Descripcion == "") {
   6:             return false;
   7:         }
   8:
   9:         if (p.Precio <= 0) {
  10:             return false;
  11:         }
  12:
  13:         return true;
  14:     }
  15: }
  16:
  17: public class CarritoDeCompras {
  18:     /* ... */
  19:     public void AgregarNuevoItem(Producto p) {
  20:
  21:         ValidadorDeProductos validador = new ValidadorDeProductos();
  22:
  23:         // Validamos el producto antes de ingresarlo
  24:         bool productoValido = validador.ValidarProducto(p);
  25:
  26:         if (productoValido) {
  27:             // Agregar el producto a la lista de compras
  28:             /* ... */
  29:         } else {
  30:             // Notificar producto inválido
  31:         }
  32:
  33:     }
  34:     /* ... */
  35: }

Ahora toda la lógica de validación de productos se encuentra fuera de la clase CarritoDeCompra, y esta se limita simplemente a crear el validador que va a encargarse de liberar al carrito de la responsabilidad de validar productos.

Si bien esta versión es más conveniente (nos da la flexibilidad de poder usar el validador en otro lugar si es que lo precisamos o podemos modificarlo sin necesidad modificar la clase CarritoDeCompra), sigue sin ser una solución ideal debido a que hay demasiado acoplamiento entre el carrito y la clase responsable de la validación. ¿A que me refiero? Imaginemos esta situación: Se agregó un requerimiento del usuario que limita la validación del precio sólo para los productos que no se encuentren dentro de una promoción, es decir, si un producto forma parte de una promoción, su precio no debe ser validado (debido a que posiblemente haya sido modificado). Para responder a este requerimiento podríamos crear otra clase validadora y usar una u otra dependiendo si el producto se encuentra o no dentro de una promoción. Es una solución rápida al problema, pero seguimos limitados a sólo estas únicas dos clases de validaciones y si precisamos personalizarlas en algún momento, vamos a tener que volver a tocar el código del carrito. Es acá donde podemos aplicar DI y pasarle el ‘control’ de la creación de la clase que realice las validaciones a quien consuma los servicios del carrito, liberándonos de la lógica de la instanciación.

Para ello vamos a hacer algunos cambios. Lo primero es hacer que la clase que representa al carrito dependa de una abstracción y no de una implementación en particular de una clase validadora. Para ello, creamos una interface como la siguiente:

   1: public interface IValidadorDeProductos {
   2:     bool ValidarProducto(Producto p);
   3: }
   4:
   5: public class ValidadorDeProductosComunes : IValidadorDeProductos {
   6:
   7:     public virtual bool ValidarProducto(Producto p) {
   8:
   9:         if (p.Descripcion == "") { return false; }
  10:
  11:         if (p.Precio <= 0) { return false; }
  12:
  13:         return true;
  14:     }
  15: }
  16:
  17: public class ValidadorDeProductosEnPromocion : IValidadorDeProductos {
  18:
  19:     public virtual bool ValidarProducto(Producto p) {
  20:
  21:         if (p.Descripcion == "") { return false; }
  22:
  23:         return true;
  24:     }
  25: }
  26:
  27: public class ValidadorDeProductosLimitados : ValidadorDeProductosComunes {
  28:
  29:     public virtual bool ValidarProducto(Producto p) {
  30:
  31:         bool esValido = base.ValidarProducto(p);
  32:
  33:         if (!esValido) { return false; }
  34:
  35:         return HayEnStock(p);
  36:     }
  37:
  38:     private bool HayEnStock(Producto p) {
  39:         /* ... */
  40:     }
  41: }

Como se puede ver, podemos crear una jerarquía de validadores (lo que promueve la reutilización del código) y todos compatibles con nuestro carrito, el cual quedaría así:

   1: public class CarritoDeCompras {
   2:     /* ... */
   3:     public void AgregarNuevoItem(Producto p, IValidadorDeProductos validador) {
   4:
   5:         // Validamos el producto antes de ingresarlo
   6:         bool productoValido = validador.ValidarProducto(p);
   7:
   8:         if (productoValido) {
   9:             // Agregar el producto a la lista de compras
  10:             /* ... */
  11:         } else {
  12:             // Notificar producto inválido
  13:         }
  14:     }
  15:     /* ... */
  16: }

En éste último ejemplo se puede ver porque llamamos a este patrón ‘inyección de dependencias’: estamos ‘inyectando’ una dependencia (el validador) a un objeto (el carrito), liberándolo a este de la tarea de instanciar, fabricar o recuperar la misma (invertimos el control de la creación del validador).

Hay distintos tipos de DI. Los más comunes son: por interface, por propiedad y por constructor.

Inyección de dependencias por interface (Interface Injection)

El ejemplo anterior del carrito muestra como se aplicó DI por interface. Inyectar dependencias por interface significa que se expone una interface que le permite a un objeto proveer las dependencias a otro. En nuestro ejemplo, la clase WebSite inyecta un validador al carrito a través de la interface que expone (el método AgregarNuevoItem()). En realidad, lo que acabo de decir no es del todo cierto. Este tipo de inyección refiere a la implementación de una interface, la cual provea una manera de aceptar dependencias. En nuestro caso no hay ninguna inteface de este tipo, por lo que la interface expuesta es la de la propia clase, pero podría existir una interface que todos los carritos (en caso de existir más de un tipo) que acepten productos deban implementar:

   1: public interface ICarritoDeCompras {
   2:     void AgregarNuevoItem(Producto p, IValidadorDeProductos validador);
   3: }

De este modo, todos los carritos de compras se ven obligados a aceptar un validador, forzando así la inyección de dependencias.

Inyección de dependencias por propiedad (Setter Injection)

Este tipo de DI se da cuando la dependencia se provee con una propiedad. Nuestro código quedaría así si usáramos este tipo de DI:

   1: public class CarritoDeCompras {
   2:    /* ... */
   3:    public IValidadorDeProductos Validador { get; set; }
   4:
   5:    public void AgregarNuevoItem(Producto p) {
   6:
   7:        // Validamos el producto antes de ingresarlo
   8:        bool productoValido = this.Validador.ValidarProducto(p);
   9:
  10:        if (productoValido) {
  11:            // Agregar el producto a la lista de compras
  12:            /* ... */
  13:        } else {
  14:            // Notificar producto inválido
  15:        }
  16:    }
  17:    /* ... */
  18: }

La DI por propiedad no debería usarse cuando la inyección es obligatoria, ya que el hecho que se haga mediante una propiedad nos da la libertad de no setear esa propiedad (intencionalmente o no), teniendo que contemplar ese caso cada vez que hagamos uso de la dependencia. Algo a tener en cuenta, es que la propiedad puede heredarse de una clase o implementarse con una interface, con lo que también estaríamos haciendo DI por interface. Muchas veces esta forma de inyección es la ofrecida por clases cuyos constructores son privados o no tenemos acceso a ellos.

Inyección de dependencias por constructor (Constructor Injection)

Este es uno de los tipos más comunes de DI. La dependencia simplemente se inyecta en el constructor de la clase que hace uso de la misma. Así se vería el ejemplo con este tipo de DI:

   1: public class CarritoDeCompras {
   2:    /* ... */
   3:    private IValidadorDeProductos Validador { get; set; }
   4:
   5:    public CarritoDeCompras(IValidadorDeProductos validador) {
   6:        this.Validador = validador;
   7:    }
   8:
   9:    public void AgregarNuevoItem(Producto p) {
  10:
  11:        // Validamos el producto antes de ingresarlo
  12:        bool productoValido = this.Validador.ValidarProducto(p);
  13:
  14:        if (productoValido) {
  15:            // Agregar el producto a la lista de compras
  16:            /* ... */
  17:        } else {
  18:            // Notificar producto inválido
  19:        }
  20:    }
  21:    /* ... */
  22: }

Algunos ejemplos

Al comienzo de este post vimos un ejemplo real de la aplicación de IoC. Ahora voy a mostrar dos casos en donde se aplica DI.

El primero se da en la clase System.Web.UI.Control. Cuando cargamos una página, todos los controles de la misma se renderizan en HTML para que puedan ser cargados por nuestros browsers. Este renderizado se realiza en el método RenderControl(), el cual acepta como parámetro una instancia de la clase System.Web.UI.HtmlTextWriter, que no es mas ni menos un TextWriter especializado en escribir HTML. Esto es así debido a que cada control se ‘dibuja’ sobre el HtmlTextWriter, quien va a ser el que se encargue mas adelante de devolver el código HTML de la pagina para que sea presentado por el browser. Cada control sabe como representarse a sí mismo. Un control TextBox va a renderizar un <input type=’text’ … />, un control HyperLink va a renderizar <a href=’…’ /> y un GridView, un <table>…</table>, pero ningún control sabe como generar con el código renderizado, simplemente se limitan a darle al HtmlTextWriter instrucciones sobre como renderizarse y nada mas. Por otro lado, el HtmlTextWriter si sabe como armar el código de la pagina y es él el que ‘da forma’ a los controles, es él el que sabe que los tags de cierre siempre tienen la forma </xxxx> y que los atributos se escriben sólo en los tags de apertura. En fin, acá vemos dos objetos diferentes, con responsabilidades diferentes e íntimamente relacionados (un control no sirve de nada si no puede renderizarse), pero el control no sabe como crear un HtmlTextWriter, ni de dónde sacarlo. El writer es inyectado al método RenderControl() aplicando DI por interface (todos los controles web tienen que sobreescribir el método RenderControl() viendose obligados a aceptar la inyección).

El otro ejemplo es la clase SqlCommand. Un comando depende siempre de una conexión a una DB para poder ejecutarse y es por eso que la misma le es provista mediante su constructor o su propiedad Connection. El comando nunca crea, abre o cierra una conexión, este se limita a enviar una solicitud de ejecución de SQL a una instancia de SQLServer usando la conexión provista y nada mas.

Esto no termina acá y hay mucho mas por ver. Les sugiero los siguientes enlaces para seguir con el tema:

¡Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in Diseño, Patrones | Etiquetado: , , | 2 Comments »

Creación de interfaces fluidas

Posted by Gerardo Contijoch en diciembre 3, 2008

Las interfaces fluidas se están poniendo de moda últimamente, o por lo menos eso me parece a mi. Cada vez son mas los frameworks que exponen interfaces fluidas o ‘fluent interfaces’ para facilitar su uso (Rhino Mocks posiblemente sea el ejemplo más famoso). Es difícil definir lo que es una interface fluida sin un buen ejemplo. Básicamente, es una forma de exponer los miembros de clases (o lo que es lo mismo, exponer sus interfaces) de modo que su uso sea sencillo y rápido y natural. Su uso se da principalmente sobre objetos configurables o con muchos parámetros. Veamos de que hablo.

Dada la siguiente clase:

   1: public class Computadora {
   2:
   3:     public string Microprocesador { get; set; }
   4:
   5:     public int CantidadDeRAM { get; set; }
   6:
   7:     public int EspacioEnDisco { get; set; }
   8:
   9:     public bool IncluyeGrabadoraDeDVD { get; set; }
  10:
  11: }

Si quisiésemos configurar nuestra computadora, haríamos lo siguiente:

   1: Computadora miComputadora = new Computadora();
   2:
   3: miComputadora.Microprocesador = "AMD Turion64 X2";
   4: miComputadora.CantidadDeRAM = 4;
   5: miComputadora.EspacioDeDisco = 320;
   6: miComputadora.IncluyeGrabadoraDeDVD = true;

No parece para nada complicado, pero vean como podríamos configurarla utilizando interfaces fluidas:

   1: Computadora miComputadora = new Computadora().ConMicro("AMD Turion64 X2").ConRAM(4).ConEspacio(320).ConGrabadoraDeDVD();

En una sola línea de código logramos lo que nos llevaba 5 antes. Imaginen el beneficio de aplicar esta técnica en objetos con 10 propiedades a configurar. Por supuesto que podemos usar sobrecarga de constructores para lograr la configuración completa del objeto en el momento de instanciarlo, pero los constructores no nos dan la posibilidad de elegir el orden de los parámetros, y siempre estaríamos limitados a un set fijo de ellos que puede no resultarnos práctico.

Las interfaces fluidas no solo se usan para configurar instancias, también podemos encadenar método para que sean ejecutados en secuencia:

   1: miComputadora.Bootear().IniciarSO().Loguearse("usuario", "pass").ChequearMail();

La posibilidad de encadenar métodos le dan a este patrón su otro nombre de ‘method chaining’. Lograr este encadenamiento es muy sencillo, simplemente hay que devolver la instancia actual en cada método y ahí ya tenemos listo el objeto para volver a invocar otro método sobre él. Éste sería uno de los métodos utilizados para configurar la clase Computadora:

   1: public class Computadora {
   2:
   3:     /* ... */
   4:
   5:     public Computadora ConMicro(string micro) {
   6:         this.Microprocesador = micro;
   7:         return this;
   8:     }
   9:     /* ... */
  10: }

Pero no todo termina ahí. ¿qué sucede cuando no tenemos acceso al código de la clase por la cual queremos ‘fluir’ o simplemente no queremos sobrecargarla de métodos utilitarios y opcionales? Para ello veamos otro ejemplo, que por cierto, es mucho mas útil que el anterior.

Imaginemos que en determinado punto de nuestra aplicación debemos enviar un mail, normalmente haríamos algo así:

public void UnMetodo() {
    //...
    EnviarMail("mi_amigo@mail.com", "gerardo.contijoch@mail.com", "Hola amigo!");
    //...
}
public void EnviarMail(string destinatario, string remitente, string mensaje) {
    MailMessage mail = new MailMessage();
    mail.To.Add(destinatario);
    mail.From = new MailAddress(remitente);
    mail.Body = mensaje;
    SmtpClient smtp = new SmtpClient();
    /* ... configuramos smtp ...*/
    smtp.Send(mail);
}

El principal problema de esta solución es que con el fin de encapsular la lógica de envío del mail, estamos creando un método con parámetros fijos y poco flexibles (es decir, hay que recompilar la aplicación si se modifican los parámetros). Podríamos crear sobrecargas pero eso llevaría mucho código extra y seguiría el problema de la flexibilidad si no hay ninguna sobrecarga que nos sea útil (por ejemplo, si queremos especificar mas de un destinatario, cuando todas las sobrecargas aceptan sólo uno). En fin, el mismo problema que teníamos con los constructores anteriormente.

En esta ocasión la técnica consiste en crear una clase extra que haga de wrapper de la clase original y nos ofrezca la fluidez que buscamos:

   1: public class MailMessageFluentInterface {
   2:
   3:     private MailMessage mail = null;
   4:
   5:     public MailMessageFluentInterface() : this(null) {}
   6:
   7:     public MailMessageFluentInterface(MailMessage mail) {
   8:         if (mail == null) {
   9:             this.mail = new MailMessage();
  10:         } else {
  11:             this.mail = mail;
  12:         }
  13:     }
  14:
  15:     public MailMessageFluentInterface Para(string direccionDestinatario) {
  16:         this.mail.To.Add(direccionDestinatario);
  17:         return this;
  18:     }
  19:
  20:     public MailMessageFluentInterface Para(MailAddress direccionDestinatario) {
  21:         this.mail.To.Add(direccionDestinatario);
  22:         return this;
  23:     }
  24:
  25:     public MailMessageFluentInterface De(string direccionRemitente, string remitente) {
  26:         var rte = new MailAddress(direccionRemitente, remitente);
  27:         return this.De(rte);
  28:     }
  29:
  30:     public MailMessageFluentInterface De(MailAddress direccionRemitente) {
  31:         this.mail.From = direccionRemitente;
  32:         return this;
  33:     }
  34:
  35:     public MailMessageFluentInterface ConAsunto(string asunto) {
  36:         this.mail.Subject = asunto;
  37:         return this;
  38:     }
  39:
  40:     public MailMessageFluentInterface ConMensaje(string mensaje) {
  41:         this.mail.Body = mensaje;
  42:         return this;
  43:     }
  44:
  45:     public MailMessageFluentInterface ConMensajeHtml(string mensajeHtml) {
  46:         this.mail.IsBodyHtml = true;
  47:
  48:         return this.ConMensaje(mensajeHtml);
  49:     }
  50:
  51:     public void Enviar() {
  52:         /* Codigo de ejemplo simplificado */
  53:         SmtpClient smtp = new SmtpClient();
  54:         smtp.Send(this.mail);
  55:     }
  56: }

De modo que el código se simplificaría pudendo quedar así:

   1: public void UnMetodo() {
   2:     //...
   3:     new MailMessageFluentInterface().De("gerardo.contijoc@mail.com", "Gerardo Contijoch").Para("un_amigo@mail.com").ConMensaje("Hola amigo!").Enviar();
   4:     //...
   5: }

Sin embargo esta solución no es de lo mejor. Noten que ahora tenemos que tener conocimiento de la nueva clase y tenemos que instanciarla nosotros mismos, cuando en realidad queremos crear un mail. No es del todo intiutivo. ¿No seria ideal que la propia clase MailMessage nos simplificara la tarea?

Bueno, eso es posible, gracias a los métodos de extensión:

   1: public static class MailExtensions {
   2:     public static MailMessageFluentInterface Configurar(this MailMessage mail) {
   3:         return new MailMessageFluentInterface(mail);
   4:     }
   5: }
   6:
   7: /* ... */
   8: public void UnMetodo() {
   9:     //...
  10:      new MailMessage().Configurar().De("gerardo.contijoc@mail.com", "Gerardo Contijoch").Para("un_amigo@mail.com").ConMensaje("Hola amigo!").Enviar();
  11:     //...
  12: }

Otra opción válida sería hacer que todos los métodos de MailMessageFluentInterface sean métodos de extensión de la clase MailMessage (haciendo innecesaria la creación de MailMessageFluentInterface y la llamada a Configurar() ), pero eso llenaría a MailMessage de métodos redundantes (debido a que ya existen las propiedades) que solo tendríamos interés de usar cuando estamos creando un mail y nada mas. Yo prefiero dejar las cosas por separado e independizar el contenido de ambas clases.

Y eso es todo por el momento. Me quedó en el tintero un par de ideas sobre la creación de interfaces fluidas más complejas (y útiles), pero como son solo ideas, por el momento me las quedo yo.

¡Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in Diseño, Patrones | Etiquetado: , , | 1 Comment »

Uso de ExpectedExceptionAttribute para testear excepciones

Posted by Gerardo Contijoch en diciembre 2, 2008

Hace tiempo que se viene hablando sobre el uso (¿mal uso?) del atributo ExpectedExceptionAttribute en NUnit o MSTest (y en cualquier otro framework de testing que lo tenga). En realidad el problema esta en el hecho de que se use el atributo y no en la forma de usarse. Según la documentación de NUnit, ExpectedExceptionAttribute “es la manera de indicar que la ejecución de un test va a provocar una excepción”.

Veamos un ejemplo de su uso (usando MSTest). Supongamos que tenemos que modelar un negocio en donde se venden cosas. Este es el código a testear:

    7
    8 public class Negocio {
    9
   10     public int Stock { get; private set; }
   11
   12     public Negocio(int stockInicial) {
   13         if (stockInicial <= 0) {
   14             throw new ArgumentOutOfRangeException("El stock no puede ser menor o igual a 0.");
   15         }
   16
   17         this.Stock = stockInicial;
   18     }
   19
   20     public void Vender(int cantidadDeUnidades) {
   21
   22         if (Stock < cantidadDeUnidades) {
   23             throw new ArgumentOutOfRangeException("No hay suficiente stock para vender.");
   24         }
   25
   26         /* procesamiento de la venta... */
   27
   28         this.Stock -= cantidadDeUnidades;
   29     }
   30 }

Como se ve es muy sencillo e incluye un par de validaciones básicas.

Ahora creamos un test para el método Vender para asegurarnos de que se esta actualizando correctamente el stock luego de realizar una venta.

   36
   37 [TestMethod]
   38 public void Vender_actualiza_stock_luego_de_venta() {
   39
   40     // Inicializamos nuestro negocio con un stock de 10 unidades
   41     var n = new Negocio(10);
   42
   43     // Vendemos 5
   44     n.Vender(5);
   45
   46     Assert.AreEqual(5, n.Stock, "No se actualizó correctamente el stock de unidades luego de una venta.");
   47 }

Si ejecutamos el test, veremos que es pasado sin problemas. Ahora creamos un test para asegurarnos que falla cuando no hay stock suficiente.

   48
   49 [TestMethod]
   50 [ExpectedException(typeof(ArgumentOutOfRangeException))]
   51 public void Vender_falla_si_no_hay_suficiente_stock() {
   52
   53     // Inicializamos nuestro negocio
   54     var n = new Negocio(0);
   55
   56     n.Vender(5);
   57
   58 }

Noten el uso de ExpectedExceptionAttribute para asegurarnos que el método Vender efectivamente falla provocando una excepción del tipo ArgumentOutOfRangeException.

Si ejecutamos el test, el mismo va a ser pasado sin mayores inconvenientes (debido a que va a fallar como es esperado), pero hay un grave problema oculto (que en este ejemplo es bastante evidente, pero no siempre lo es): El test esta fallando, pero no donde nosotros esperamos que falle (en el método Vender), sino que falla en el constructor de la clase Negocio (debido a que la cantidad pasada como stock inicial es inválida). Esto significa que nunca llegamos a ejecutar el método Vender y por lo tanto, no sabemos si efectivamente el mismo falla o no cuando no hay stock suficiente.

Para solucionar este problema, lo que se puede hacer es encerrar el código que debe fallar entre bloques try/catch y verificar que efectivamente se esta lanzando una excepción en ese punto (y no antes o en otro lugar), pero esa no es una solución muy elegante y hay que escribir demasiado código extra. Es por ello que las últimas versiones de los frameworks de testing mas populares incluyen clases y métodos helpers que nos facilitan la tarea de verificar que se esta lanzando una excepción.

Por ejemplo, NUnit 2.5 (aún en etapa beta) tiene el método Throws (de la clase Assert) que nos facilita la tarea haciendo que el código para testear la excepción quede de la siguiente manera:

   56 Assert.Throws<ArgumentOutOfRangeException>( () => n.Vender(5) );

Si la llamada al método Vender NO lanza una excepción del tipo ArgumentOutOfRangeException, entonces se lanza una excepción del tipo AssertionException, o lo que es lo mismo, se aborta el test en curso.

Lamentablemente MSTest no incluye ningún método similar y es por ello que tome la idea e hice un ‘port’ de ese método a MSTest:

    5
    6 static class CustomAssert {
    7
    8     /// <summary>
    9     /// Verifica que la ejecución de <paramref name="accion"/> lance una excepción.
   10     /// </summary>
   11     /// <typeparam name="TExcepcion">Tipo de la excepción esperada.</typeparam>
   12     /// <param name="accion"><see cref="Action"/> a ejecutar.</param>
   13     /// <returns>Excepción lanzada.</returns>
   14     /// <exception cref="AssertFailedException">La ejecución de <paramref name="accion"/> no produjo una excepción del tipo esperado.</exception>
   15     public static TExcepcion Throws<TExcepcion>(Action accion)
   16         where TExcepcion : System.Exception {
   17
   18         return Throws<TExcepcion>(accion, null);
   19     }
   20
   21     /// <summary>
   22     /// Verifica que la ejecución de <paramref name="accion"/> lance una excepción.
   23     /// </summary>
   24     /// <typeparam name="TExcepcion">Tipo de la excepción esperada.</typeparam>
   25     /// <param name="accion"><see cref="Action"/> a ejecutar.</param>
   26     /// <param name="mensaje">Mensaje a mostrar en caso de que no se lance la excepción esperada.</param>
   27     /// <returns>Excepción lanzada.</returns>
   28     /// <exception cref="AssertFailedException">La ejecucion de <paramref name="accion"/> no produjo una excepción del tipo esperado.</exception>
   29     public static TExcepcion Throws<TExcepcion>(Action accion, string mensaje)
   30         where TExcepcion : System.Exception {
   31         try {
   32             accion.Invoke();
   33         } catch (Exception ex) {
   34             CompararTiposYFallarSiSonDistintos(typeof(TExcepcion), ex.GetType(), mensaje);
   35             return ex as TExcepcion;
   36         }
   37
   38         Assert.Fail(string.Format("Se esperaba una excepción del tipo {0}, pero no se produjo ninguna.", typeof(TExcepcion).ToString()));
   39
   40         // Llamada necesaria para que compile
   41         return null;
   42     }
   43
   44     private static void CompararTiposYFallarSiSonDistintos(Type tipoEsperado, Type tipoActual, string mensaje) {
   45         if (tipoEsperado != tipoActual) {
   46             if (string.IsNullOrEmpty(mensaje)) {
   47                 mensaje = string.Format("Se esperaba una excepción del tipo {0}, pero se produjo una excepción del tipo {1}.", tipoEsperado.ToString(), tipoActual.GetType().ToString());
   48             }
   49
   50             Assert.Fail(mensaje);
   51         }
   52     }
   53
   54 }

Tuve que crear la clase CustomAsserts debido a que la clase Assert es estática y por lo tanto no se le pueden agregar métodos de extensión. Un detalle a tener en cuenta es que este método siempre devuelve la excepción producida por lo que se puede verificar que los valores de las propiedades de la misma sean los correctos. Esto ultimo es muy útil con excepciones del tipo ArgumentException (y derivadas) ya que normalmente querremos verificar que los argumentos que tiene problemas sean los que esperamos y no otros. Veamos un ejemplo:

   17
   18 public void MetodoConParametros(string param1, int param2) {
   19     if (param1 == string.Empty) {
   20         throw new ArgumentException("param1 no puede ser vacío.", "param1");
   21     }
   22
   23     if (param2 > 5) {
   24         throw new ArgumentException("param2 no puede ser mayor a 5.", "param2");
   25     }
   26 }
   27
   28 [TestMethod]
   29 public void MetodoConParametros_falla_si_param1_es_vacio() {
   30
   31     var ex = CustomAssert.Throws<ArgumentException>(() => MetodoConParametros("", 4));
   32
   33     Assert.AreEqual<string>("param1", ex.ParamName, "Se esperaba que param1 fuese el parámetro con problemas.");
   34 }
   35
   36 [TestMethod]
   37 public void MetodoConParametros_falla_si_param2_es_mayor_a_5() {
   38
   39     var ex = CustomAssert.Throws<ArgumentException>(() => MetodoConParametros("test", 80));
   40
   41     Assert.AreEqual<string>("param2", ex.ParamName, "Se esperaba que param2 fuese el parámetro con problemas.");
   42 }

Bien, eso es todo por el momento, espero que esta clase les sea tan útil como me resulta a mi (ya forma parte de mi ‘core’ para testing).

Pueden bajar la clase CustomAsserts aquí.

¡Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in Testing | Etiquetado: , , , , | 3 Comments »

Hello world!

Posted by Gerardo Contijoch en diciembre 2, 2008

Hacía mucho tiempo que no escribía un ‘Hello World!’. Casi tanto tiempo como el que llevo leyendo blogs. Empecé a leerlos mas que nada por simple curiosidad, veía que muchas de las personas que diseñaban/arquitectaban/programaban las aplicaciones y sites que usamos día a día los leían y recomendaban su lectura. Empecé con un par de blogs, principalmente sobre programación .NET y C#. No tardé mucho tiempo en notar que esos blogs que yo leía, también eran leídos por personas que sabían mucho sobre lo que hablaban, por lo que los empecé a seguir también. Hoy en día me es imposible vivir sin consultar Google Reader cada 5 minutos, no porque sea adicto a internet, sino porque soy adicto a aprender cosas nuevas todo el tiempo. Para mi la ‘blogosfera’ (que palabra tan fea!) es algo asi como una plataforma de estudio, donde uno puede aprender, preguntar y enseñar lo que quiera (por lo menos en lo que refiere a programación) gratuitamente. Todo esta ahí, solo hay que saber buscar.

Lamentablemente, la mayoría del contenido sobre programación esta en inglés y eso deja fuera a muchas personas. Esa es una de las razones por la que me decidí por empezar este blog. Todavía no tengo muy en claro la dirección que va a tomar, pero lo que sé es que básicamente va a contener muchas de las cosas que encuentro en los distintos blogs que leo, pero tratadas en español.

¿Y que va a haber en el blog? Principalmente temas relacionados con .NET, ASP.NET MVC (mi nuevo chiche), LINQ, Visual Studio, Unit Testing, Mocking y patrones.

Bueno, suficientes presentaciones por ahora, nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in Personal | Etiquetado: | 1 Comment »