<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Pure .NET Development</title>
	<atom:link href="http://jimenezroda.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://jimenezroda.wordpress.com</link>
	<description>Javier Jimenez Roda's .NET Development Blog</description>
	<lastBuildDate>Sat, 10 Sep 2011 07:10:54 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='jimenezroda.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/25f121fd2f7b509207c1d0578c6711b0?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Pure .NET Development</title>
		<link>http://jimenezroda.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://jimenezroda.wordpress.com/osd.xml" title="Pure .NET Development" />
	<atom:link rel='hub' href='http://jimenezroda.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Using ASP.NET and Javascript through ClientScriptManager (Javascript y ASP.NET mediante el objeto ClientScriptManager)</title>
		<link>http://jimenezroda.wordpress.com/2009/09/02/using-asp-net-and-javascript-throught-clientscriptmanager-javascript-y-asp-net-mediante-el-objeto-clientscriptmanager/</link>
		<comments>http://jimenezroda.wordpress.com/2009/09/02/using-asp-net-and-javascript-throught-clientscriptmanager-javascript-y-asp-net-mediante-el-objeto-clientscriptmanager/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 10:13:54 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[ASP.NET 2.0 / 3.5]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=232</guid>
		<description><![CDATA[Pese a que a muchos de nosotros nos facilitaría la vida en sobremanera, ejecutar todas las acciones de nuestra aplicación web en el lado del servidor no siempre es la mejor opción ni mucho menos la más aconsejable.  ASP.NET nos permite controlar todos los aspectos de nuestra aplicación desde el lado del servidor, pero con [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=232&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Pese a que a muchos de nosotros nos facilitaría la vida en sobremanera, ejecutar todas las acciones de nuestra aplicación web en el lado del servidor no siempre es la mejor opción ni mucho menos la más aconsejable.  ASP.NET nos permite controlar todos los aspectos de nuestra aplicación desde el lado del servidor, pero con el coste añadido de realizar round-trips (ida y venidas) al servidor mediante Postbacks y todo lo que eso implica: tratamiento de la petición y renderización de la respuesta, tiempos de espera, renderización de la página (completa!) en el cliente&#8230;</p>
<p>Cierto es que con la llegada de la tecnología AJAX a nuestras vidas, hemos conseguido reducir parte de ese coste (con las peticiones asíncronas y la renderización parcial de página), pero, pese a todo, todavía quedan aspectos en los que la mejor opción sigue siendo ejecutar código en el lado del cliente. El lenguaje más utilizado para programar ése código del lado del cliente es Javascript, por lo que se nos hace necesario orquestrar la comunicación entre ASP.NET en el servidor (incluso si usamos ASP.NET AJAX) y Javascript en el cliente.<span id="more-232"></span>Este artículo no pretende ser una referencia al lenguaje Javascript, sino a cómo añadir código Javascript a nuestras páginas aspx (WebForms) y realizar la comunicación entre el cliente y el servidor utilizando este lenguaje. En cualquier caso, existe una lista casi interminable de recursos en la web en los que podremos encontrar o informarnos acerca de los temas más básicos o extremos de este lenguaje.</p>
<p>Así pues, comenzaremos con la foma más simple de añadir código Javascript a nuestra página ASP.NET: añadiendo el código al código ASP/html de nuestra página. El siguiente ejemplo muestra cómo añadir una función javascript que ejecuta un Alert mostrando un texto cualquiera:</p>
<div id="attachment_277" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-277" title="javascriptsimple" src="http://jimenezroda.files.wordpress.com/2009/08/javascriptsimple.png?w=500&#038;h=338" alt="Ejemplo simple de uso de Javascript desde ASP.NET" width="500" height="338" /><p class="wp-caption-text">Ejemplo simple de uso de Javascript desde ASP.NET</p></div>
<p>Como se puede observar en el código, hemos añadido el código Javascript directamente en el código ASP/html de nuestro WebForm. VS2008 y posteriores proporcionan IntelliSense para Javascript, con lo que añadir este tipo de código resulta muy fácil.<br />
En este ejemplo, se define una función que simplemente muestra el mensaje que le llega como parámetro. Desde el control Button (es un control de ASP.NET, por lo tanto del lado del servidor) invocaremos a esta función pasándole el mensaje que queramos. Para ello, indicamos el atributo <em>OnClientClick</em> indicándole la función a ejecutar en el cliente cuando se haga click en el botón. Justo después de ejecutar la función indicada, el Button hace un Postback al servidor.</p>
<p>El resultado de ejecutar este código es el siguiente:</p>
<div id="attachment_279" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-279" title="simple1" src="http://jimenezroda.files.wordpress.com/2009/08/simple1.png?w=500&#038;h=259" alt="Ejemplo de ejecución sin pulsar el botón" width="500" height="259" /><p class="wp-caption-text">Ejemplo de ejecución sin pulsar el botón</p></div>
<div id="attachment_280" class="wp-caption aligncenter" style="width: 377px"><img class="size-full wp-image-280" title="simple2" src="http://jimenezroda.files.wordpress.com/2009/08/simple2.png?w=367&#038;h=256" alt="Ejemplo 1 tras pulsar el botón y ejecutarse el código Javascript" width="367" height="256" /><p class="wp-caption-text">Ejemplo 1 tras pulsar el botón y ejecutarse el código Javascript</p></div>
<p>Hasta aquí todo muy simple, ¿verdad? Bien, avancemos un poco.<br />
En muchas ocasiones disponemos de un archivo con extensión .js que hemos utilizado a modo Librería de funciones Javascript. Nos gustaría hacer referencia a dicho archivo con tal de poder reutilizarlo en varias apliaciones. Pues bien, vamos a comprobar cómo se hace paso a paso:</p>
<ol>
<li>Añadimos o creamos el archivo en nuestra solución (podemos utilizar el menu <em>Añadir &#8211; Elemento Existente  </em>para seleccionar un archivo existente o bien <em>Añadir &#8211; Nuevo elemento</em> para crear un nuevo archivo vacío).</li>
<li>Para añadir una referencia a este archivo desde nuestra página .aspx, es tan fácil como, en la vista de código ASP/HTML, arrastramos el archivo desde el explorador de soluciones a la linea en la que queremos añadir la referencia.
<p><div id="attachment_285" class="wp-caption aligncenter" style="width: 699px"><img class="size-full wp-image-285" title="addreference" src="http://jimenezroda.files.wordpress.com/2009/08/addreference.png?w=689&#038;h=230" alt="Arrastramos el archivo desde el explorador de soluciones a la linea de código dónde queremos situar la referencia." width="689" height="230" /><p class="wp-caption-text">Arrastramos el archivo desde el explorador de soluciones a la linea de código dónde queremos situar la referencia.</p></div></li>
<li>Una vez hecho esto, ya podemos hacer referencia, desde el código ASP/Html a las funciones Javascript definidas dentro del archivo referenciado. Para demostrarlo, añadimos un nuevo botón a nuestra página de ejemplo que hace referencia a la función <em>mostrarFechaYHoraDelCliente</em> definida dentro del archivo que hemos referenciado. A continuación se muestra tanto el código añadido a la página .aspx como el contenido del archivo referenciado:
<div id="attachment_286" class="wp-caption aligncenter" style="width: 555px"><img class="size-full wp-image-286 " title="addcodeTime" src="http://jimenezroda.files.wordpress.com/2009/08/addcodetime.png?w=545&#038;h=194" alt="Añadimos un campo input del tipo button a la página. Al hacer click en el botón se ejecuta la función que contiene el archivo referenciado." width="545" height="194" /><p class="wp-caption-text">Añadimos un campo input del tipo button a la página. Al hacer click en el botón se ejecuta la función que contiene el archivo referenciado.</p></div>
<div id="attachment_287" class="wp-caption aligncenter" style="width: 664px"><img class="size-full wp-image-287 " title="javascriptmedium" src="http://jimenezroda.files.wordpress.com/2009/08/javascriptmedium.png?w=654&#038;h=382" alt="Código Javascript contenido en el archivo referenciado." width="654" height="382" /><p class="wp-caption-text">Código Javascript contenido en el archivo referenciado.</p></div>
<p>Este código Javascript recoge la fecha y hora del cliente y la muestra justo debajo de todos los controles que contiene la página. En caso de referescar la página, se actualiza la hora.</li>
</ol>
<p>Una vez hemos seguido estos pasos, ya podemos ejecutar la aplicación para comprobar que todo funciona correctamente:</p>
<div id="attachment_288" class="wp-caption aligncenter" style="width: 423px"><img class="size-full wp-image-288" title="executemedium" src="http://jimenezroda.files.wordpress.com/2009/08/executemedium.png?w=413&#038;h=119" alt="Al pulsar el boton   se muestra la hora actual en el cliente." width="413" height="119" /><p class="wp-caption-text">Al pulsar el boton se muestra la hora actual en el cliente.</p></div>
<p><span style="text-decoration:underline;"><br />
 <strong>El objeto ClientScriptManager:</strong></span></p>
<p>Hasta el momento se han comentado las bases para poder añadir funcionalidad Javascript a nuestro código ASP.NET en tiempo de diseño (conceptualmente no hay mucho más que añadir. Ahora podríamos complicar el tema mucho más, añadiendo funciones Javascript que llaman a otras funciones Javascript y más controles que hagan uso de esas funciones en sus diferentes eventos), pero el concepto es el mismo que hemos comentado.</p>
<p>Ahora bien, en muchas ocasiones, el código lo generamos de forma dinámica desde el lado del servidor en función de varios parámetros. En este caso, ¿cómo hacemos para enviar código Javascript al cliente? Pues es en este contexto cuando más sentido tiene utilizar la clase ClientScriptManager.</p>
<p> Para demostrar su uso, volveremos a mostrar los mismo ejemplos pero ahora añadiremos los scripts desde el código de servidor haciendo uso del objeto ClientScriptManage. Para ello, volveremos a dejar el código ASP.NET/HTML en su estado inicial:</p>
<p> <img class="aligncenter size-full wp-image-299" title="limpio" src="http://jimenezroda.files.wordpress.com/2009/09/limpio.png?w=499&#038;h=284" alt="limpio" width="499" height="284" /></p>
<p>Una vez hecho esto, en el evento Page_Load pasaremos a utilizar el objeto ClientScriptManager para añadir nuestro código javascript. Como hicimos antes, nuestro primer ejemplo tratará de mostrar un mensaje al pulsar el botón con el título &#8220;Pulsa para ejecutar Javascript&#8221;. Para ello haremos uso del método <strong><em>RegisterClientScriptBlock</em></strong>. Este método nos permite registrar código javascript en el cliente, o lo que es lo mismo, añadir funciones javascript a la respuesta enviada desde el servidor. Para añadir la función muestraAlerta, el código es el siguiente:</p>
<div id="attachment_300" class="wp-caption aligncenter" style="width: 767px"><img class="size-full wp-image-300 " title="registerClientScriptblockAlerta" src="http://jimenezroda.files.wordpress.com/2009/09/registerclientscriptblockalerta.png?w=757&#038;h=381" alt="registerClientScriptblockAlerta" width="757" height="381" /><p class="wp-caption-text">Código que muestra el uso del método RegisterClientScriptBlock el cual añade código javascript a nuestra página.</p></div>
<p style="text-align:left;"> Y si lo ejecutáis, vereis que el efecto es exactamente el mismo que en el ejemplo anterior. Incluso podemos ver qué códgio ha sido enviado al servidor para comprobar el funcionamiento. Para ver el código, hacemos click con el botón derecho en la página y seleccionamos &#8220;Ver código fuente&#8221;. Podremos ver lo siguiente: </p>
<div id="attachment_303" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-303 " title="codigofuente" src="http://jimenezroda.files.wordpress.com/2009/09/codigofuente.png?w=650&#038;h=215" alt="Se muestra el código fuente que llega al cliente." width="650" height="215" /><p class="wp-caption-text">Se muestra el código fuente que llega al cliente.</p></div>
<p>Una vez hecho esto,  avanzaremos en el ejemplo y . tal y como hicimos en la primera parte, ahora añadiremos una referéncia a un archivo javascript existente. Para ello haremos uso del método <strong><em>RegisterClientScriptInclude</em> </strong>de la clase ClientScriptManager. Este método nos permitirá añadir la referéncia a un archivo javascript existente en nuestro servidor, o lo que es lo mismo, nos permite añadir al código html del cliente una linea tal como esta:</p>
<div><span style="font-size:x-small;color:#0000ff;"><span style="font-size:x-small;color:#0000ff;">&lt;</span></span><span style="font-size:x-small;color:#0000ff;"><span style="font-size:x-small;color:#0000ff;"><span style="font-size:x-small;color:#a31515;">script</span><span style="font-size:x-small;"> </span><span style="font-size:x-small;color:#ff0000;">src</span><span style="font-size:x-small;color:#0000ff;">=&#8221;LibreriaJavascript.js&#8221;</span><span style="font-size:x-small;"> </span><span style="font-size:x-small;color:#ff0000;">type</span><span style="font-size:x-small;color:#0000ff;">=&#8221;text/javascript&#8221;&gt;&lt;/</span><span style="font-size:x-small;color:#a31515;">script</span><span style="font-size:x-small;color:#0000ff;">&gt;</span></span></span> La siguiente imagen muestra el código necesario para conseguir esto:</div>
<div id="attachment_298" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-298 " title="clientscriptincludescript" src="http://jimenezroda.files.wordpress.com/2009/09/clientscriptincludescript.png?w=650&#038;h=270" alt="Uso del método RegisterClientScriptInclude" width="650" height="270" /><p class="wp-caption-text">Uso del método RegisterClientScriptInclude</p></div>
<p>Para que, como en el ejemplo inicial, el segundo botón pueda llamar a la función que se encuentra definida dentro del archivo, es necesario capturar el evento <em>onclick</em> y asignarle una llamada a dicho método.</p>
<div id="attachment_297" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-297 " title="clientscriptincludehtml" src="http://jimenezroda.files.wordpress.com/2009/09/clientscriptincludehtml.png?w=650&#038;h=8" alt="Modificamos el html para el submit de forma que llame a la función definida dentro del archivo javascript" width="650" height="8" /><p class="wp-caption-text">Modificamos el html para el submit de forma que llame a la función definida dentro del archivo javascript</p></div>
<p>Obvia decir que el resultado de ejecutar este ejemplo es exactamente el mismo que en la rimera parte del artículo.</p>
<p>Por último, vamos a mostrar cómo registrar una función javascript para que se ejecute al cargarse la página (de forma automática). Para ello haremos uso del método <em>RegisterStartupScript</em> de la clase <em>ClientScriptManager </em>tal y como se muestra en la siguiente imagen:</p>
<div id="attachment_302" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-302 " title="startupscript" src="http://jimenezroda.files.wordpress.com/2009/09/startupscript.png?w=650&#038;h=277" alt="La última linea muestra el código necesario para ejecutar un script al iniciar la página" width="650" height="277" /><p class="wp-caption-text">La última linea muestra el código necesario para ejecutar un script al iniciar la página</p></div>
<p> Y el resultado de ejecutar esta página es el siguiente:</p>
<div id="attachment_301" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-301" title="startuprun" src="http://jimenezroda.files.wordpress.com/2009/09/startuprun.png?w=500&#038;h=484" alt="Ejecución de la página. Se ejecuta el javascript definido al iniciar la carga." width="500" height="484" /><p class="wp-caption-text">Ejecución de la página. Se ejecuta el javascript definido al iniciar la carga.</p></div>
<p>Como se puede comprobar en la imagen, el script se ejecuta durante la carga de la página (al inicio de la misma).</p>
<p>En este artículo se ha tratado de generar código Javascript de forma manual sin hacer uso de ninguno de los miles de Frameworks existentes (y , por cierto, de gran utilidad) como podría ser <strong><em>JQuery</em></strong> (para mi gusto, uno de los mejores frameworks para trabajar con Javascript). Aunque seguramente hay muchos programadores C# que siguen siendo reticientes a aprender las características de este lenguaje de cliente. Para ellos tambien existe soluciones, como puede ser el uso de <strong><em>Script#</em></strong>, un add-in para Visual Studio que nos permite escribir funciones en C# y, tras ser compiladas, estas se traducen a Javascript y se almacenan en su correspondiente archivo .js.<br />
Así que, como podeis ver, existen muchas alternativas para todos los programadores con tal de que podamos enriquecer la experiencia de nuestros usuarios desde el propio cliente.</p>
<p>Un saludo a todos y, como siempre, espero que os sea útil!</p>
<br /> Tagged: ASP.NET, Javascript <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/232/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=232&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2009/09/02/using-asp-net-and-javascript-throught-clientscriptmanager-javascript-y-asp-net-mediante-el-objeto-clientscriptmanager/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/javascriptsimple.png" medium="image">
			<media:title type="html">javascriptsimple</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/simple1.png" medium="image">
			<media:title type="html">simple1</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/simple2.png" medium="image">
			<media:title type="html">simple2</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/addreference.png" medium="image">
			<media:title type="html">addreference</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/addcodetime.png" medium="image">
			<media:title type="html">addcodeTime</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/javascriptmedium.png" medium="image">
			<media:title type="html">javascriptmedium</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/executemedium.png" medium="image">
			<media:title type="html">executemedium</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/09/limpio.png" medium="image">
			<media:title type="html">limpio</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/09/registerclientscriptblockalerta.png" medium="image">
			<media:title type="html">registerClientScriptblockAlerta</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/09/codigofuente.png" medium="image">
			<media:title type="html">codigofuente</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/09/clientscriptincludescript.png" medium="image">
			<media:title type="html">clientscriptincludescript</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/09/clientscriptincludehtml.png" medium="image">
			<media:title type="html">clientscriptincludehtml</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/09/startupscript.png" medium="image">
			<media:title type="html">startupscript</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/09/startuprun.png" medium="image">
			<media:title type="html">startuprun</media:title>
		</media:content>
	</item>
		<item>
		<title>Using OutputCache directive (Utilizando la directiva OutputCache)</title>
		<link>http://jimenezroda.wordpress.com/2009/08/19/using-outputcache-directive-utilizando-la-directiva-outputcache/</link>
		<comments>http://jimenezroda.wordpress.com/2009/08/19/using-outputcache-directive-utilizando-la-directiva-outputcache/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 09:59:47 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[ASP.NET 2.0 / 3.5]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=243</guid>
		<description><![CDATA[Ya habíamos hablado sobre cómo hacer uso del objeto Cache de ASP.NET para poder guardar en caché aquellos objetos que almacenan datos que requieren de un largo tiempo de procesado para ser obtenidos y que no cambian con demasiada frecuéncia.  Con el uso del objeto Cache, evitábamos tener que volver a recuperar los datos (con [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=243&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Ya habíamos hablado sobre cómo hacer uso del objeto<a title="Using ASP.NET Cache object" href="http://wp.me/plsxf-3i"> Cache de ASP.NET</a> para poder guardar en caché aquellos objetos que almacenan datos que <em>requieren de un largo tiempo de procesado para ser obtenidos y que no cambian con demasiada frecuéncia</em>.  Con el uso del objeto Cache, evitábamos tener que volver a recuperar los datos (con todo lo que eso implica: realizar la conexión a la base de datos, realizar la consulta, cerrar la conexión y realizar un tratamiento de los datos si es necesario). Eso repercute en una mejora sustancial en el tiempo de procesado de una petición a un recurso determinado. Pero ¿cómo podemos reducir aún más ese tiempo?  Hasta ahora, guardamos en caché <em>el resultado de consultas a una base de datos, a un archivo o cualquier objeto cuya inicialización u obtención requiere de un tiempo notable de procesado</em>. Ahora bien, eso no quita que se deba llevar a cabo <em>toda la renderización de la página</em> pasando por cada uno de los eventos de ASP.NET (PreInit, Init, Load, PreRender, Render, etc&#8230;) para acabar generando el <em>código Html</em> que se envia finalmente al cliente. Si prestamos atención, veremos que el simple hecho de renderizar los controles de servidor (WebControls) a tags Html implica un coste elevado (pero necesario) de tiempo. Necesario si pero ¿siempre?. La respuesta es no. Si analizamos con calma las páginas de nuestro site, nos daremos cuenta de que muchas de ellas son completamente estáticas (siempre muestran el mismo contenido) y que otras disponen de contenidos dinámicos que cambian cada cierto tiempo (pero no de forma contínua, ni por usuario ni nada por el estilo).<br />
Si lo miramos así, sería genial poder guardar en Cache el resultado de la renderización de estás páginas (es decir, Cachear el códgio html que se envia al cliente) evitando así todo el proceso de renderización de la página. Es aquí donde entra en escena la directiva <em>OutputCache</em>.</p>
<p><span id="more-243"></span></p>
<p><strong>Escenario</strong>:</p>
<p>Pongámonos en situación. Con tal de demostrar el uso de la directiva <em>OutputCache</em>, desarrollaremos una pequeña aplicación web en la que se mezclen formularios web estáticos y dinámicos (como ocurre en el 90% de las aplicaciones web). La aplicación constará de una página inicial en la que se mostrará un menú mediante el cual el usuario navegará por el web site.  Crearemos un formulario web en el que el usuario especificará el nombre de un Artista y se mostrarán los Álbumes editados por dicho Artista. Por último veremos ejemplos de cómo mejorar ciertas partes del Caching mediante el uso de <em>UserControls</em>.</p>
<p><strong>OutputCache: la directiva</strong></p>
<p>La directiva <em>OutputCache</em> debe aplicarse al código ASP.NET o html de nuestra página.  La sintaxi para utilizar esta directiva es la siguiente:</p>
<p><span style="color:#ffff00;">&lt;%</span><span style="color:#0000ff;">@</span> <span style="color:#993366;">OutputCache </span><span style="color:#ff0000;">Duration</span><span style="color:#3366ff;">=</span><span style="color:#0000ff;">&#8220;x&#8221;</span> <span style="color:#ff0000;">VaryByParam</span><span style="color:#0000ff;">=</span><span style="color:#0000ff;">&#8220;none&#8221; </span><span style="color:#ffff00;">%/&gt;</span></p>
<p>Como puede observarse, además de declarar la directiva, deben especificarse como mínimo dos atributos:</p>
<ul>
<li><span style="text-decoration:underline;"><em>Duration</em></span>: especifica el tiempo que se almacena en cache el resultado de esta página</li>
<li><span style="text-decoration:underline;"><em>VaryByParam</em></span>: especifica si se debe guardar en cache una versión por cada valor de un parámetro concreto. Por ejemplo, podríamos indicar VaryByParam=&#8221;name&#8221; y se guardaría una versión de la página por cada uno de los posibles valores de la variable &#8220;name&#8221;. Si hacemos una llamada a la página con name=&#8221;javi&#8221; se guardará el resultado en cache y si luego hacemos la misma llamada pero con name=&#8221;luis&#8221; se guardará otra versión de la misma página pero con el resultado cuando la variable name=&#8221;luis&#8221;.</li>
</ul>
<p>La directiva acepta otros atributos que iremos comentando más adelante, pero estos dos son los mínimos requeridos.<br />
Como veremos más adelante, podremos configurar todos estos elementos tanto en código asp.net html como en el archivo web.config.</p>
<p>Así pues, la primera imagen que se muestra es la página principal del site:</p>
<div id="attachment_246" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-246" title="inicial" src="http://jimenezroda.files.wordpress.com/2009/08/inicial.png?w=500&#038;h=305" alt="Página principal del site" width="500" height="305" /><p class="wp-caption-text">Página principal del site</p></div>
<p>Como puede verse, la página consta de un menú de navegación y varios textos estáticos. Esta página es una firme candidata a ser &#8220;cacheada&#8221;, puesto que no parece probable que vaya a ser modificada de forma asidua y sus controles tienen datos estáticos. Si miramos el trace generado por la petición para obtener esta página, veremos lo siguiente:</p>
<div id="attachment_249" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-249" title="traceinicial" src="http://jimenezroda.files.wordpress.com/2009/08/traceinicial.png?w=500&#038;h=385" alt="Trace de la petición inicial" width="500" height="385" /><p class="wp-caption-text">Trace de la petición inicial</p></div>
<p>El tiempo total en renderizar la página es de 0.0134 segundos. Como ya hemos dicho, esta página es la candidata ideal para ser &#8220;cacheada&#8221;. Para ello, lo que haremos será añadir la directiva OutputCache a la página, tal y como se muestra en la siguiente imagen:</p>
<div id="attachment_247" class="wp-caption alignleft" style="width: 660px"><img class="size-full wp-image-247 " title="inicialoutputdirectiva" src="http://jimenezroda.files.wordpress.com/2009/08/inicialoutputdirectiva.png?w=650&#038;h=168" alt="Añadimos la directiva OutputCache con los atributos requeridos" width="650" height="168" /><p class="wp-caption-text">Añadimos la directiva OutputCache con los atributos requeridos</p></div>
<p>El resultado de añadir esta directiva es que la página no volverá a ser renderizada (atención, nos saltaremos TODO el proceso de renderización de la página, con lo que el ahorro de tiempo es máximo) y se devolverá inmediatamente el resultado al cliente. Si ahora volvemos a ejecutar la página y miramos el trace, encontraremos lo siguiente:</p>
<div id="attachment_248" class="wp-caption aligncenter" style="width: 659px"><img class="size-full wp-image-248 " title="traceconoutput" src="http://jimenezroda.files.wordpress.com/2009/08/traceconoutput.png?w=649&#038;h=386" alt="Trace con la directiva OutputCache activada." width="649" height="386" /><p class="wp-caption-text">Trace con la directiva OutputCache activada.</p></div>
<p>Como podéis observar, ni siquiera marca entrada alguna en el registro de tiempos. Eso se debe a que se ha saltado todo el proceso de renderización de la página, con lo que no se han podido calcular los tiempos invertidos en cada fase o evento del proceso. Si, el ahorro de tiempo es máximo.</p>
<p>Imaginemos ahora que, en esta misma página, tan sólo hay un elemento texto que debe ser dinámico. Pongamos, por ejemplo, que queremos que se muestre la hora del servidor en nuestra web. Claro, si cacheamos la página entera, siempre aparecerá la misma hora (hasta que caduque la caché). ¿Significa eso que ya no puedo guardar en Cache esta página? Pues no, ni mucho menos. Para este caso en concreto, en el que deseamos que cierto <em>texto</em> sea dinámico, podemos utilizar el control <strong><em>Substitution</em></strong>. Este control nos permite sustituir determinados valores de nuestra página en Cache, devolviendo así siempre el valor deseado y manteniendo en Caché la página en sí.<br />
Vamos a mostrar un ejemplo para que quede demostrado el uso del control Substitution:</p>
<p>Añadiremos, al pie de nuestra web, dos textos en los que se indicará la hora del servidor. El primero se ejecutará desde el lado del servidor, es decir, obtendremos el valor del tiempo en el evento On_Load de la página y lo mostraremos. El segundo utilizará el control <em>Substitution</em> para mostrar la hora:</p>
<p style="text-align:left;">
<div id="attachment_252" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-252 " title="substituiondiseño" src="http://jimenezroda.files.wordpress.com/2009/08/substituiondiseno.png?w=650&#038;h=277" alt="Muestra cómo queda el diseño de la página. Además se muestra el control Substitution en la caja de herramientas." width="650" height="277" /><p class="wp-caption-text">Muestra cómo queda el diseño de la página. Además se muestra el control Substitution en la caja de herramientas.</p></div>
<p style="text-align:left;">Para que el control Substitution funcione correctamente, es necesario especificar, en sus propiedades, el método al que debe llamar para obetener el texto a mostrar.  El código de la página principal se muestra en la siguiente imagen:</p>
<p style="text-align:left;">
<div id="attachment_255" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-255" title="codesubs" src="http://jimenezroda.files.wordpress.com/2009/08/codesubs.png?w=500&#038;h=344" alt="Se recoge la fecha del servidor en el evento Load de la página y en el método llamado por el control Substitution" width="500" height="344" /><p class="wp-caption-text">Se recoge la fecha del servidor en el evento Load de la página y en el método llamado por el control Substitution</p></div>
<p style="text-align:left;">Ahora podemos ejecutar la aplicación. Al recibir la primera petición, ambos controles muestran el mismo valor:</p>
<p style="text-align:left;">
<div id="attachment_253" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-253" title="subsrun1" src="http://jimenezroda.files.wordpress.com/2009/08/subsrun1.png?w=500&#038;h=418" alt="Ambas lineas muestran el mismo valor al recibir la primera petición (ya que la página no está cacheada)" width="500" height="418" /><p class="wp-caption-text">Ambas lineas muestran el mismo valor al recibir la primera petición (ya que la página no está cacheada)</p></div>
<p style="text-align:left;">Una vez se ha recibido la respuesta, el servidor a cacheado la página, con lo que si ahora refrescamos, como la duración es de 60 segundos, el servidor nos devolverá la página cacheada, pero aplicando la sustitución al control substitution, por lo que el resultado es este:</p>
<p style="text-align:left;">
<div id="attachment_254" class="wp-caption aligncenter" style="width: 507px"><img class="size-full wp-image-254" title="subsrun2" src="http://jimenezroda.files.wordpress.com/2009/08/subsrun2.png?w=497&#038;h=416" alt="El tiempo mostrado por el control Substitution se ha refrescado, mientras que el otro no, ya que proviene de la página Cacheada." width="497" height="416" /><p class="wp-caption-text">El tiempo mostrado por el control Substitution se ha refrescado, mientras que el otro no, ya que proviene de la página Cacheada.</p></div>
<p>Como puede verse, la primera linea mantiene el valor que hay en la página Cacheada mientras que el valor de la segunda linea se ha actualizado gracias al uso del control Substitution, mostrando así la hora del servidor actualizada.</p>
<p>Pero bien, no nos vamos a ganar el cielo tan fácilmente no? Claro&#8230;y que ocurre con aquellas páginas cuyos datos són dinámicos (bien porque contienen controles dinamicos como listview, gridview, formview, detailsview,etc&#8230; o bien porque las construimos de forma dinámica).<br />
Bueno, lo primero que hay que comentar es que no todo puede ser cacheado. Utilizando la Cache ganaremos en velocidad (mejor dicho, tiempo de respuesta), pero la contrapartida es que aumentaremos la memoria ocupada y esto, cuando llega a ciertos límites, acaba produciendo una disminución de la velocidad y finalmente un colapso en el servidor. Debemos elegir cuidadosamente aquellas páginas/elementos a cachear.</p>
<p>Segundo: debemos elegir aquellas páginas que varien por parámetros cuyos rangos de valores no sean demasiado grandes, pues por cada uno de los valores comprendidos en dicho rango se almacenaría una cópia de la página.</p>
<p>Bien, veamos qué podemos hacer con una página que contiene datos dinámicos.</p>
<p>La página que trataremos de &#8220;agilizar&#8221; es la que se muestra en las siguientes imágenes:</p>
<div id="attachment_258" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-258" title="album1" src="http://jimenezroda.files.wordpress.com/2009/08/album1.png?w=500&#038;h=316" alt="El usuario selecciona un Artista y se le muestran todos los Álbumes de que se dispone." width="500" height="316" /><p class="wp-caption-text">El usuario selecciona un Artista y se le muestran todos los Álbumes de que se dispone.</p></div>
<div id="attachment_257" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-257" title="album2" src="http://jimenezroda.files.wordpress.com/2009/08/album2.png?w=500&#038;h=514" alt="Otro ejemplo, con un Artista diferente" width="500" height="514" /><p class="wp-caption-text">Otro ejemplo, con un Artista diferente</p></div>
<p>Bien, podemos observar que esta página contiene datos estáticos (la parte superior de la misma, en la que se muestra el título, el menú, etc..) y datos dinámicos (el DropDownList + el GridView). Evidentemente no podemos guardar en cache una versión de la página por cada uno de los Artistas que hay en el DropDownList (ya que la lista es interminable), Cachear la página tal y como hicimos en el ejemplo anterior no tiene sentido, pues siempre veríamos el mismo album y artista. Entonces ¿está página no puede cachearse? La respuesta es no tal y como está. El resultado del DropDownList y del GridView no podremos cachearlos, pues son dinámicos (en cualquier caso podríamos cachear el datasource del dropDownList y, quizás el del GridView con tal de no volver a buscar en la base de datos). Pero fijémonos bien. Hay una parte en la página que es estática. Podríamos reducir el tiempo necesario para renderizar esta página si pudiéramos cachear <span style="text-decoration:underline;"><em>sólamente esa parte</em></span>. Pues lo cierto es que podemos hacerlo. El tema consiste en poner toda esa parte estática dentro de un <strong>UserControl</strong> y cachear ese UserControl tal y como hicimos en el ejemplo anterior.</p>
<div id="attachment_259" class="wp-caption aligncenter" style="width: 425px"><img class="size-full wp-image-259" title="cabecera" src="http://jimenezroda.files.wordpress.com/2009/08/cabecera.png?w=415&#038;h=208" alt="UserControl que contiene la cabecera estática" width="415" height="208" /><p class="wp-caption-text">UserControl que contiene la cabecera estática</p></div>
<p>Ahora, añadimos la cabecera tanto a la página principal, como a la página de búsqueda de albums:</p>
<div id="attachment_260" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-260" title="cabecera2" src="http://jimenezroda.files.wordpress.com/2009/08/cabecera2.png?w=500&#038;h=496" alt="Añadimos la cabecera al Webform de búsqueda de Albums" width="500" height="496" /><p class="wp-caption-text">Añadimos la cabecera al Webform de búsqueda de Albums</p></div>
<p>Antes de marcar el UserControl para ser cacheado, vamos a comprobar el tiempo que tarda la petición en el servidor:</p>
<div id="attachment_261" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-261 " title="tracealbum" src="http://jimenezroda.files.wordpress.com/2009/08/tracealbum.png?w=650&#038;h=455" alt="Muestra el trace inicial (sin outputCache del UserControl)" width="650" height="455" /><p class="wp-caption-text">Muestra el trace inicial (sin outputCache del UserControl)</p></div>
<p>Ahora añadiremos la directiva <em>OutputCache</em> a nuestro UserControl, tal y como se muestra en la siguiente imagen:</p>
<div id="attachment_262" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-262 " title="outpualbum" src="http://jimenezroda.files.wordpress.com/2009/08/outpualbum.png?w=650&#038;h=159" alt="Añadimos la directiva OutputCache al UserControl de la misma forma que hicimos con la página principal." width="650" height="159" /><p class="wp-caption-text">Añadimos la directiva OutputCache al UserControl de la misma forma que hicimos con la página principal.</p></div>
<p>Y finalmente volveremos a realizar la petición para volver a comprobar el tiempo que se tarda en generar la respuesta a la petición:</p>
<p style="text-align:left;">
<div id="attachment_263" class="wp-caption aligncenter" style="width: 855px"><img class="size-full wp-image-263  " title="tracealbum2" src="http://jimenezroda.files.wordpress.com/2009/08/tracealbum2.png?w=845&#038;h=564" alt="Se puede comprobar la disminución del tiempo necesaria para generar la respuesta a la petición" width="845" height="564" /><p class="wp-caption-text">Se puede comprobar la disminución del tiempo necesario para generar la respuesta a la petición</p></div>
<p style="text-align:left;">Se puede apreciar la diferencia del tiempo invertido en generar la misma respuesta que en la petición anterior.</p>
<p style="text-align:left;"><span style="text-decoration:underline;"><strong>Configurando la directiva OutputCache:</strong></span></p>
<p style="text-align:left;">Hasta el momento sólo hemos utilizado dos atributos de la directiva OutputCache: Duration y VaryByParam. Pero la directiva admite otros atributos que nos pueden proporcionar funcionalidades muy interesantes:</p>
<ul>
<li><em>Shared</em>: determina si se puede compartir la versión cacheada con múltiples páginas.</li>
<li><em>SqlDependency</em>: al igual que con el objeto Cache, podemos crear una dependencia a una tabla de una base de datos concreta.</li>
<li><em>VaryByCustom</em>: Nos permite especificar si queremos guardar una versión de la página por cada Browser y versión o bien por cada valor diferente de un string que le pasamos.</li>
<li><em>VaryByHeader</em>: Guarda una versión por cada valor diferente de una cabecera http determinada.</li>
<li><em>NoStore</em>: Se envia la cabecera no-store. No disponible para UserControls.</li>
<li><em>Location</em>: especifica las cabeceras de cache que se van a enviar al cliente. De esta forma se determina si la versión de la página se almacena en el cliente, en el servidor, en un proxy, etc&#8230;</li>
</ul>
<p><span style="text-decoration:underline;"><strong>El objeto HttpCachePolicy:</strong></span></p>
<p>Una forma alternativa de controlar el OutputCache es mediante el objeto <em>HttpCachePolicy </em>del cual obtenemos unas instancia a través del objeto <em>Response</em>. Con este objeto podemos configurar, programaticamente lo mismo que hemos configurado mediante la directiva OutputCache, aunque nos ofrece algunas funcionalidades extras, como por ejemplo el SlidingExpiration o la renovación del timeout (si una página cacheada tiene una duración de 20 segundos y en el segundo 19 alguien realiza una petición, la duración vuelve a renovarse 20 segundos más).</p>
<p>Para recuperar el objeto, como ya he comentado antes, lo haremos a través del objeto Response tal que así:</p>
<p style="text-align:left;">
<div id="attachment_266" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-266 " title="httpcachepolicy" src="http://jimenezroda.files.wordpress.com/2009/08/httpcachepolicy.png?w=650&#038;h=190" alt="El objeto HttpCachePolicy" width="650" height="190" /><p class="wp-caption-text">El objeto HttpCachePolicy</p></div>
<p>el nombre <span style="text-decoration:underline;">Cache </span>no es demasiado adecuado en este contexto, ya que podría confundirse con el objeto Cache que tratamos en el artículo anterior. Por ese motivo debemos tener claros los conceptos.</p>
<p><span style="text-decoration:underline;"><strong>Cache Dependency</strong></span>:</p>
<p>Al igual que ocurre con el objeto Cache, podemos añadir dependencias a la directiva OutputCache, de forma que podamos caducar la cache en función de la dependencia/s que le hemos añadido.</p>
<p>Para añadir una dependencia a la directiva OutputCache, tan solo deberemos utilizar el objeto <strong>Response </strong>y su método <em>AddCacheDependency </em>como se muestra en la siguiente imagen:</p>
<div id="attachment_271" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-271" title="cachedependency1" src="http://jimenezroda.files.wordpress.com/2009/08/cachedependency1.png?w=500&#038;h=142" alt="Añadimos una dependencia a archivo a la directiva OutputCache" width="500" height="142" /><p class="wp-caption-text">Añadimos una dependencia a archivo a la directiva OutputCache</p></div>
<p>En cambio, si queremos añadir una dependencia a una tabla de SqlServer debemos modificar la directiva añadiéndole el atributo <em>SqlDependency</em>.</p>
<p style="text-align:left;">
<div id="attachment_272" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-272 " title="sqldependency1" src="http://jimenezroda.files.wordpress.com/2009/08/sqldependency1.png?w=650&#038;h=33" alt="Modificamos la directiva para que acepte dependencias a Sql" width="650" height="33" /><p class="wp-caption-text">Modificamos la directiva para que acepte dependencias a Sql</p></div>
<p style="text-align:left;">Este atributo acepta dos tipos de valores diferentes:</p>
<ul>
<li><span style="text-decoration:underline;">CommandNotification</span>: si queremos utilizar la notificación de sentencia de SQL Server 2005 y posteriores (no disponible si aplicamos la directiva a UserControls).</li>
<li><span style="text-decoration:underline;">String con DatabaseName/Table</span>: un string que define el nombre de la base de datos y la tabla a la que se añade la dependencia.</li>
</ul>
<p>Finalmente, añadiremos la dependencia mediante el objeto Response, como en el ejemplo anterior.<br />
Cabe recordar que para dependencias SQL es necesario añadir las correspondientes entradas en el archivo de configuración web.config (tal y como se comentó en el artículo anterior).</p>
<div id="attachment_273" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-273" title="sqldependency2" src="http://jimenezroda.files.wordpress.com/2009/08/sqldependency2.png?w=500&#038;h=82" alt="Configuramos la dependencia Sql en el archivo web.config (o en el especificado en el atributo configSource)" width="500" height="82" /><p class="wp-caption-text">Configuramos la dependencia Sql en el archivo web.config (o en el especificado en el atributo configSource)</p></div>
<p><span style="text-decoration:underline;"><strong>OutputCacheProfiles:</strong></span></p>
<p>Hasta el momento, cualquier configuración sobre la directiva OutputCache la hemos realizado directamente en el código de nuestra página aspx. En muchas ocasiones nos gustaría tener la ibertad de poder modificar, en tiempo de ejecución, los parámetros de dicha directiva (por ejemplo, queremos cambiar el atributo Duration para que la Cache caduque antes o más tarde). En estos casos podemos utilizar (y de hecho es una práctica muy recomendable) los archivos de configuración de la aplicación web para almacenar lo que se conoce como <em>OutputCache profiles</em>.<br />
Estos profiles no son más que los mismos atributos que configuramos en la directiva OutputCache con la ventaja de poder modificarlos directamente en el archivo web.config (o en otro archivo xml siempre que se configure el atributo configSource del nodo correctamente).</p>
<p>Para añadir un nuevo profile al archivo de configuración, solo es necesario crear la siguiente estructura xml:</p>
<div id="attachment_268" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-268" title="outputcacheprofiles" src="http://jimenezroda.files.wordpress.com/2009/08/outputcacheprofiles.png?w=500&#038;h=106" alt="Ejemplo de configuración de un profile de OutputCache" width="500" height="106" /><p class="wp-caption-text">Ejemplo de configuración de un profile de OutputCache</p></div>
<p>El archivo web.config en VS2005 y 2008 dispone de IntelliSense, por lo que no es necesario recordar cada unos de los atributos posibles. Es suficiente con seleccionarlos de la lista.<br />
Podemos añadir tantos profiles como queramos. Una vez añadido el profile, sólo nos queda indicarle a nuestra página aspx que debe utilizar dicho profile para configurar la directiva OutputCache. Esto lo conseguimos modificando la directiva de la siguiente forma:</p>
<p><span style="color:#ffff00;">&lt;%</span><span style="color:#0000ff;">@</span> <span style="color:#800000;">OutputCache </span><span style="color:#ff0000;">CacheProfile</span><span style="color:#0000ff;">=&#8221;MiConfiguracion&#8221;</span><span style="color:#ffff00;">%&gt;</span></p>
<p><span style="color:#ffff00;"><span style="color:#000000;">Con este simple cambio, nuestra directiva leerá su configuración del archivo de configuración de la aplicación web.</span></span></p>
<p><span style="color:#ffff00;"><span style="color:#000000;">Y eso es todo. Creo que se han abordado ámpliamente todos los aspectos relacionados con la directiva outputcache, dando una visión global bastante completa. Espero que os sirva en vuestros proyectos.</span></span></p>
<p><span style="color:#ffff00;"><span style="color:#000000;">Un saludo!<br />
</span></span></p>
<br /> Tagged: .NET, ASP.NET, C# <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/243/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/243/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/243/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/243/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/243/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/243/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/243/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/243/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/243/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/243/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/243/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/243/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/243/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/243/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=243&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2009/08/19/using-outputcache-directive-utilizando-la-directiva-outputcache/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/inicial.png" medium="image">
			<media:title type="html">inicial</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/traceinicial.png" medium="image">
			<media:title type="html">traceinicial</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/inicialoutputdirectiva.png" medium="image">
			<media:title type="html">inicialoutputdirectiva</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/traceconoutput.png" medium="image">
			<media:title type="html">traceconoutput</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/substituiondiseno.png" medium="image">
			<media:title type="html">substituiondiseño</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/codesubs.png" medium="image">
			<media:title type="html">codesubs</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/subsrun1.png" medium="image">
			<media:title type="html">subsrun1</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/subsrun2.png" medium="image">
			<media:title type="html">subsrun2</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/album1.png" medium="image">
			<media:title type="html">album1</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/album2.png" medium="image">
			<media:title type="html">album2</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/cabecera.png" medium="image">
			<media:title type="html">cabecera</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/cabecera2.png" medium="image">
			<media:title type="html">cabecera2</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/tracealbum.png" medium="image">
			<media:title type="html">tracealbum</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/outpualbum.png" medium="image">
			<media:title type="html">outpualbum</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/tracealbum2.png" medium="image">
			<media:title type="html">tracealbum2</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/httpcachepolicy.png" medium="image">
			<media:title type="html">httpcachepolicy</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/cachedependency1.png" medium="image">
			<media:title type="html">cachedependency1</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/sqldependency1.png" medium="image">
			<media:title type="html">sqldependency1</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/sqldependency2.png" medium="image">
			<media:title type="html">sqldependency2</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/outputcacheprofiles.png" medium="image">
			<media:title type="html">outputcacheprofiles</media:title>
		</media:content>
	</item>
		<item>
		<title>Using ASP.NET Cache Object (Utilizando el objeto Cache de ASP.NET)</title>
		<link>http://jimenezroda.wordpress.com/2009/08/13/using-asp-net-cache-object-utilizando-el-objeto-cache-de-asp-net/</link>
		<comments>http://jimenezroda.wordpress.com/2009/08/13/using-asp-net-cache-object-utilizando-el-objeto-cache-de-asp-net/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 15:32:13 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[ASP.NET 2.0 / 3.5]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=204</guid>
		<description><![CDATA[Muchos son los beneficios que se pueden obtener al hacer un uso correcto de la Cache de ASP.NET, pero cierto es que muchos programadores son reticentes a su uso o bien desconocen todas las opciones que ASP.NET nos ofrece con tal de Cachear objetos. Con este artículo pretendo “desmitificar” el uso de la caché de [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=204&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:left;">Muchos son los beneficios que se pueden obtener al hacer un uso correcto de la Cache de ASP.NET, pero cierto es que muchos programadores son reticentes a su uso o bien desconocen todas las opciones que ASP.NET nos ofrece con tal de Cachear objetos. Con este artículo pretendo “desmitificar” el uso de la caché de ASP.NET, mostrando ejemplos prácticos de sus diferentes usos. En este primer artículo, nos centraremos en el objeto Cache, mientras que en la segunda parte nos centraremos en la directiva <em>OutputCache</em>.<span id="more-204"></span>En el desarrollo de aplicaciones web es muy importante evitar, en la medida de lo posible, los roundtrips (o idas y venidas del servidor) siempre y cuando estos sean redundantes, es decir, para obtener la misma información de nuevo. Así mismo, es importante que el tiempo de procesado de una solicitud sea el más bajo posible, ya que así aumentaremos el rendimiento del servidor, permitiendo un incremento del número de usuario concurrentes que nuestra aplicación puede soportar.</p>
<p style="text-align:left;">Tan importante como evitar roundtrips al servidor, es evitar el tiempo de procesado que se invierte en recuperar información persistente (almacenada en una base de datos o bien en un archivo) de forma repetitiva.</p>
<p style="text-align:left;">Imaginemos la siguiente situación:</p>
<p style="text-align:left;">Disponemos de una formulario web (Webform o página web) en el que , al pulsar el botón “Obtener datos” se muestran los datos de una tabla en un GridView. Esta tabla y los datos que contiene se generarán dinámicamente al pulsar el botón. La página se muestra en la siguiente imagen, así como el código utilizado para generar la tabla y su contenido (en esta série de ejemplos no utilizaremos ASP.NET AJAX para la comunicación asíncrona):</p>
<div class="mceTemp mceIEcenter" style="text-align:left;">
<dl class="wp-caption aligncenter">
<dt class="wp-caption-dt"><img class="size-full wp-image-206 " title="Diseño de la página" src="http://jimenezroda.files.wordpress.com/2009/08/pagina.png?w=451&#038;h=283" alt="Diseño de la página" width="451" height="283" /></dt>
<dd class="wp-caption-dd">Diseño de la página. En esta imagen se muestra el diseño de la página con la que se pretende demostrar el uso del objeto Cache. Contiene simplemente una tabla (GridView) y un botón con el que se llena de datos la tabla.</dd>
</dl>
</div>
<p style="text-align:left;">
<div class="mceTemp mceIEcenter" style="text-align:left;">
<dl class="wp-caption aligncenter">
<dt class="wp-caption-dt"><img class="size-full wp-image-205 " title="Código inicial" src="http://jimenezroda.files.wordpress.com/2009/08/codigo-inicial.png?w=649&#038;h=701" alt="Aquí se muestra el código inicial de la página. De hecho simplemente se muestra el evento click del botón, en el que se crea de forma dinámica una tabla y se rellena de datos con tal de bindarla, posteriormente, al GridView. Este es el código base sobre el que modificaremos y haremos uso del objeto Cache." width="649" height="701" /></dt>
<dd class="wp-caption-dd">Aquí se muestra el código inicial de la página. De hecho simplemente se muestra el evento click del botón, en el que se crea de forma dinámica una tabla y se rellena de datos con tal de bindarla, posteriormente, al GridView. Este es el código base sobre el que modificaremos y haremos uso del objeto Cache.</dd>
</dl>
</div>
<p style="text-align:left;">Bien, si prestamos atención veremos que el contenido de la tabla que se muestra mediante el control GridView es estático (siempre el mismo) sin embargo, cada vez que pulsamos el botón “Obtener datos” invertimos un preciado tiempo de proceso a <em>volver a generar los mismos datos</em>. De hecho, podríamos comprobar el tiempo que se tarda en generar estos datos al mirar en el Trace de nuestra web accediendo a la página trace.axd (cabe recordar que para poder acceder a esta página debemos añadir el nodo <span style="color:#0000ff;">&lt;</span><span style="color:#800000;">trace </span><span style="color:#ff0000;">enabled</span><span style="color:#0000ff;">=</span>&#8220;<span style="color:#0000ff;">true</span>&#8221; <span style="color:#ff0000;">pageOutput</span><span style="color:#0000ff;">=</span>&#8220;<span style="color:#0000ff;">false</span>&#8220;<span style="color:#0000ff;">/&gt;</span> a nuestro archivo web.config):</p>
<div class="mceTemp mceIEcenter" style="text-align:left;">
<dl class="wp-caption aligncenter">
<dt class="wp-caption-dt"><img class="size-full wp-image-208" title="Resultado de la página tras pulsar el botón Obtener datos" src="http://jimenezroda.files.wordpress.com/2009/08/pulsarboton.png?w=500&#038;h=326" alt="Resultado de la página tras pulsar el botón Obtener datos" width="500" height="326" /></dt>
<dd class="wp-caption-dd">Resultado de la página tras pulsar el botón Obtener datos</dd>
</dl>
</div>
<p style="text-align:left;">Ahora muestro una captura del Trace para esta página (accediendo a http://localhost:1312/trace.axd)</p>
<p style="text-align:left;">
<div class="mceTemp mceIEcenter" style="text-align:left;">
<dl class="wp-caption aligncenter">
<dt class="wp-caption-dt"><img class="size-full wp-image-207 " title="Trace de la página inicial" src="http://jimenezroda.files.wordpress.com/2009/08/primertrace.png?w=650&#038;h=390" alt="Se muestra un trace de la página inicial sin hacer uso del objeto Cache." width="650" height="390" /></dt>
<dd class="wp-caption-dd">Se muestra un trace de la página inicial sin hacer uso del objeto Cache.</dd>
</dl>
</div>
<p style="text-align:left;">Evidentemente, la creación de una tabla dinámica con tan pocos datos es muy rápida, pero se puede observar como el tiempo transcurrido entre el primer mensaje en rojo y el segundo es de 0,000404 segundos (un tiempo insignificante). Ahora modificaremos el código mostrado anteriormente para hacer uso del objeto <strong>Cache </strong>de ASP.NET.</p>
<p style="text-align:left;"><strong>El objeto Cache</strong>:</p>
<p style="text-align:left;">ASP.NET dispone de un objeto llamado Cache, que nos facilitará mucho la inserción y recuperación de objetos de caché (además de la gestión de los mismo como veremos más adelante). Mediante el uso del objeto Cache, podremos almacenar en memoria (durante un tiempo configurarable) cualquier objeto que sea <em>serializable.</em></p>
<p style="text-align:left;">El objeto Cache se usa de la misma forma que el objeto ViewState o Session, es decir, mediante un <strong>indexador</strong>. Este objeto siempre devuelve objetos del tipo Object, por lo que será necesario realizar un cast al tipo de objeto esperado. No se ha comentado anteriormente (y es importante), pero ASP.NET instancia un objeto Cache por cada una de las aplicaciones que maneja (es decir, no es a nivel de usuario sino de aplicación).</p>
<p style="text-align:left;">De forma esquemática, podemos utilizar el objeto Cache tal que así:</p>
<p style="text-align:left;"><em>Cache[“Miobjeto”]=miObjeto;</em></p>
<p style="text-align:left;"><em> </em></p>
<p style="text-align:left;"><em> </em>O bien</p>
<p style="text-align:left;"><em>Tipo miObjeto=(Tipo)Cache[“Miobjeto”];</em></p>
<p style="text-align:left;">Ahora bien, para utilizar el objeto Cache, normalmente se siguen tres pasos básicos:</p>
<ol>
<li>Comprobar si el objeto existe en la Cache</li>
<li>Si existe, lo recuperamos de la cache.</li>
<li>En caso contrario, creamos el objeto (es decir, realizamos la consulta a la base de datos, leemos el archivo o creamos los objetos como en este ejemplo, o lo que sea necesario para generar los datos). Finalmente, añadimos el objeto a Cache para poder utilizarlo posteriormente.</li>
</ol>
<p>Procedemos a modificar el código anterior siguiendo estos tres pasos:</p>
<p style="text-align:left;">
<div id="attachment_215" class="wp-caption aligncenter" style="width: 659px"><img class="size-full wp-image-215 " title="Código con uso de Cache" src="http://jimenezroda.files.wordpress.com/2009/08/codigo-cache1.png?w=649&#038;h=692" alt="Aquí se muestra el nuevo código que hace uso de la cache siguiendo los tres pasos previamente definidos." width="649" height="692" /><p class="wp-caption-text">Aquí se muestra el nuevo código que hace uso de la cache siguiendo los tres pasos previamente definidos.</p></div>
<p style="text-align:left;">Y a continuación se muestra una segunda captura del trace para observar que hemos conseguido reducir algo que ya de por sí era de un coste muy bajo:</p>
<p style="text-align:left;">
<div id="attachment_214" class="wp-caption aligncenter" style="width: 659px"><img class="size-full wp-image-214  " title="Trace de la página utilizando la Cache" src="http://jimenezroda.files.wordpress.com/2009/08/segundotrace.png?w=649&#038;h=416" alt="Se puede observar una reducción del tiempo de proceso invertido en generar la respuesta para esta petición." width="649" height="416" /><p class="wp-caption-text">Se puede observar una reducción del tiempo de proceso invertido en generar la respuesta para esta petición (marcada con el mensaje &quot;Usamos la cache&quot;).</p></div>
<p style="text-align:left;">El efecto del uso de la cache es más evidente cuando el proceso de recolección de datos (mediante una consulta a base de datos o leyendo de un archivo) es más lento que el que se muestra como ejemplo, pero creo que este ejemplo es bastante claro y facilita asumir los conceptos.</p>
<p style="text-align:left;"><strong>Actualizando la cache:</strong></p>
<p style="text-align:left;">Seguramente a estas alturas alguien ya habrá clamado contra el cielo: &#8220;¡Pero los datos que utilizo en mi aplicación no son estáticos! ¡La cache no me sirve!&#8221;. Pues no estás en lo cierto. Evidentemente ASP.NET ya dispone de los elementos necesarios para gestionar este escenario. Ahora entraremos a describir las <strong>CacheDependencies</strong>.</p>
<p style="text-align:left;">Podemos asociar nuestros objetos en Cache con otros elementos que harán que esta entrada sea eliminada, obligando a que la próxima petición que requiera ese objeto/s vuelva a obtenerlos, guardando así una versión actualizada de los mismos en Cache. Esta asociación entre nuestros objetos en Cache y elementos externos se produce a través de las <em>CacheDependecies </em>(o dependencias de Cache).</p>
<p style="text-align:left;"><strong><em>Escenario:</em></strong><br />
Imaginemos el siguiente escenario. Tenemos la misma tabla dinámica que hemos definido anteriormente (la tabla generica) pero serializada en un archivo con formato xml. Queremos que nuestro DataTable (el DataTable generica del ejemplo anterior) en Cache se elimine cuando alguien modifique el archivo xml que contiene sus datos. De esta forma, en la próxima petición ASP.NET se verá obligado a obtener los datos leyendo el archivo de nuevo y guardando el DataTable en Cache (así obtenemos los datos actualizados).<br />
Para ello, hemo definido un nuevo botón al ejemplo anterior (botón que serializa el DataTable a un archivo xml, añadíendole un nuevo registro) y hemos modificado el código del botón <em>ObtenerDatos.</em></p>
<p style="text-align:left;">
<div id="attachment_220" class="wp-caption aligncenter" style="width: 855px"><img class="size-full wp-image-220  " title="Método ObtenerDatos modificado" src="http://jimenezroda.files.wordpress.com/2009/08/obtenerdatos2.png?w=845&#038;h=486" alt="Modificamos el método ObtenerDatos para que: 1) Lea la tabla del archivo. 2) Guarde la tabla en Cache con una dependencia al archivo." width="845" height="486" /><p class="wp-caption-text">Modificamos el método ObtenerDatos para que: 1) Lea la tabla del archivo. 2) Guarde la tabla en Cache con una dependencia al archivo.</p></div>
<p style="text-align:left;">En este código, añadiremos los elementos a la Cache mediante el uso del método estático <strong><em>Add </em></strong>(no utilizaremos el indexador). Este método nos permitirá definir la <em>CacheDependency </em>a utilizar. Deberemos especificar, además de la clave y el objeto a serializar (como en el uso con indexador) el tiempo máximo que va a permanecer en Cache el objeto (he definido DateTime.MaxValue para definir un tiempo ilimitado) y un TimeSliding (tiempo sin uso que hace que el objeto sea eliminado de la Cache. He definido que tras 5 días sin ser usado, debe eliminarse el objeto de <em>Cache</em>). Podeis obtener toda la información a cerca de este método <a title="Cache.Add method definition" href="http://msdn.microsoft.com/es-es/library/system.web.caching.cache.add.aspx" target="_blank">aquí</a>.</p>
<p style="text-align:left;">Ahora muestro el código del método ModificarArchivoXml, el cual añade un nuevo registro a la tabla y la guarda en el archivo xml, cancelando asi el objeto en Cache (por la dependencia que añadimos antes).</p>
<p style="text-align:left;">
<div id="attachment_219" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-219 " title="Método modificarArchivoXml." src="http://jimenezroda.files.wordpress.com/2009/08/modificararchivo.png?w=650&#038;h=304" alt="Método que añade un nuevo elemento a la tabla Generica y la serializa al archivo xml." width="650" height="304" /><p class="wp-caption-text">Método que añade un nuevo elemento a la tabla Generica y la serializa al archivo xml.</p></div>
<p>Ahora, el diseño de nuestra página es este:</p>
<div id="attachment_218" class="wp-caption aligncenter" style="width: 323px"><img class="size-full wp-image-218" title="Diseño de la página" src="http://jimenezroda.files.wordpress.com/2009/08/diseno2.png?w=313&#038;h=287" alt="Nuevo diseño de la interfaz gráfica de la página." width="313" height="287" /><p class="wp-caption-text">Nuevo diseño de la interfaz gráfica de la página.</p></div>
<p>Ahora pasamos a ejecutar la página. Mostraré capturas del Trace para que pueda comprobarse tanto el uso de la cache, como de las dependencias que hemos declarado asi como para comprobar cómo el hecho de guardar los datos en un archivo implica un mayor tiempo de procesado y cómo el uso de la Cache lo reduce drásticament.</p>
<p>Primero, pulsamos el botón <strong>ObtenerDatos </strong>para leer los datos del archivo:</p>
<p style="text-align:left;">
<div id="attachment_217" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-217   " title="trace2sincache" src="http://jimenezroda.files.wordpress.com/2009/08/trace2sincache.png?w=650&#038;h=307" alt="La primera petición necesita leer los datos del archivo, lo que consume mayor tiempo de proceso que en el ejemplo anterior." width="650" height="307" /><p class="wp-caption-text">La primera petición necesita leer los datos del archivo, lo que consume mayor tiempo de proceso que en el ejemplo anterior.</p></div>
<p>Observad que la petición ha tardado 0,005340 segundos en procesarse. Ahora  pulsamos el botón de nuevo para obtener los datos de <strong><em>Cache</em></strong>.</p>
<p style="text-align:left;">
<div id="attachment_222" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-222 " title="trace2concache" src="http://jimenezroda.files.wordpress.com/2009/08/trace2concache.png?w=650&#038;h=307" alt="Ahora obtenemos los datos de la cache. Observar la reducción de tiempo." width="650" height="307" /><p class="wp-caption-text">Ahora obtenemos los datos de la cache. Observad la reducción de tiempo.</p></div>
<p style="text-align:left;">Al pasar por Cache, la petición ha tardado 0.000803 (un 150% más rápido). Ahora pulsamos el botón ModificarArchivoXml:</p>
<p style="text-align:left;">
<div id="attachment_224" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-224 " title="trace2nuevafila" src="http://jimenezroda.files.wordpress.com/2009/08/trace2nuevafila.png?w=650&#038;h=291" alt="Puede verse cómo pasamos por el método que añade una nueva fila a la tabla y la serializa al archivo xml." width="650" height="291" /><p class="wp-caption-text">Puede verse cómo pasamos por el método que añade una nueva fila a la tabla y la serializa al archivo xml.</p></div>
<p style="text-align:left;">Por último, volvemos a pulsar el botón ObtenerDatos. Ahora podremos ver como vuelve a leer los datos del archivo (nosotros en el código en ningún momento hemos cancelado la Cache o eliminado el objeto de la misma. Lo único que hemos hecho es modificar el archivo xml y, mediante la dependencia, la Cache a borrado el objeto, con lo que obliga al método a volver a leer el archivo para deserializar la tabla).</p>
<p style="text-align:center;">
<div id="attachment_223" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-223 " title="trace2connuevafila" src="http://jimenezroda.files.wordpress.com/2009/08/trace2connuevafila.png?w=650&#038;h=306" alt="Hemos tenido que volver a leer el archivo, ya que la cache había caducado por la dependencia." width="650" height="306" /><p class="wp-caption-text">Hemos tenido que volver a leer el archivo, ya que la cache había caducado por la dependencia.</p></div>
<p><strong>Creando dependencias con tablas de bases de datos</strong></p>
<p>Una vez llegados a este punto, seguro que alguien ha vuelto a clamar al cielo: &#8220;¡Pero mis datos no son ni estáticos ni los tengo en un archivo, los tengo en una base de datos! La caché no me sirve&#8221;. Pues vuelves a equivocarte. Con la llegada al mundo del framework 2.0,  el equipo de desarrollo de ASP.NET solucionó este problema. Ahora podemos crear dependencias con tablas de base de datos, de forma que mientras la tabla siga inalterada, el objeto permanecerá en Cache, pero en el momento en que esa tabla sea modificada, entonces la Cache para el objeto quedará caducada, y la siguiente petición deberá volver a acceder a la base de datos para actualizar el objeto en Cache.<br />
Para ello haremos uso del objeto <strong>SqlCacheDependency</strong>. Este objeto, al igual que el objeto CacheDependency hacía con un archivo, nos permitirá crear una dependencia entre un objeto en Cache y una tabla en una base de datos concreta.</p>
<p>Lo primero que debemos hacer es añadir a nuestro archivo web.config, la siguiente entrada para:</p>
<ol>
<li>Habilitar las dependencias de Cache con Sql</li>
<li>Especificar la cadena de conexión (o las cadenas de conexión si hay varias) con las que se comprobará la modificación de la tabla a supervisar.</li>
</ol>
<p>El código quedaría tal que así:</p>
<p style="text-align:left;">
<div id="attachment_237" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-237 " title="sqlcachewebconfig" src="http://jimenezroda.files.wordpress.com/2009/08/sqlcachewebconfig1.png?w=650&#038;h=195" alt="Muestra el código xml necesario para activar las dependencias de Cache a SQL" width="650" height="195" /><p class="wp-caption-text">Muestra el código xml necesario para activar las dependencias de Cache a SQL</p></div>
<p style="text-align:left;">Ahora, modificaremos el código del método ObtenerDatos para que :</p>
<ol>
<li>Realice la consulta a la base de datos mediante LinQ (no es requisito ya que puede hacerse mediante cualquier otro método de ADO.NET).</li>
<li>Cree la dependencia entre la base de datos y la Cache.</li>
</ol>
<p>Aquí está el código necesario para hacerlo:</p>
<p style="text-align:left;">
<div id="attachment_236" class="wp-caption aligncenter" style="width: 660px"><img class="size-full wp-image-236 " title="obtenerdatos3" src="http://jimenezroda.files.wordpress.com/2009/08/obtenerdatos3.png?w=650&#038;h=367" alt="Código necesario para crear la dependencia entre Cache y sql." width="650" height="367" /><p class="wp-caption-text">Código necesario para crear la dependencia entre Cache y sql.</p></div>
<p style="text-align:left;">Finalmente, muestro el resultado de una consulta. Los tiempos de ejecución son análogos a los del ejemplo anterior, por lo que omito colocar las capturas del Trace.</p>
<p style="text-align:left;">
<div id="attachment_235" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-235" title="artistas" src="http://jimenezroda.files.wordpress.com/2009/08/artistas.png?w=500&#038;h=475" alt="Resultado de la consulta de Artistas." width="500" height="475" /><p class="wp-caption-text">Resultado de la consulta de Artistas.</p></div>
<p style="text-align:left;">Y eso es todo. Espero haberos ayudado a desmitificar el tema de Cache en ASP.NET. Como podeis comprobar es muy simple de utilizar y nos aporta grandes beneficios. Cabe recordar que no hay que confundir el uso del objeto Cache con el uso de la directiva OutputCache, que trato en otro artículo distinto. Pese que los dos hablan de Cachear datos, uno se refiere a Cachear ciertas partes de una página mientras que el otro se refiere a Cachear <em>todo el resultado de una petición</em>.</p>
<p style="text-align:left;">Como siempre, espero vuestro comentarios! Gracias! <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align:left;">
<br /> Tagged: .NET, ASP.NET, C# <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/204/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/204/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/204/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/204/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/204/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/204/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/204/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=204&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2009/08/13/using-asp-net-cache-object-utilizando-el-objeto-cache-de-asp-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/pagina.png" medium="image">
			<media:title type="html">Diseño de la página</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/codigo-inicial.png" medium="image">
			<media:title type="html">Código inicial</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/pulsarboton.png" medium="image">
			<media:title type="html">Resultado de la página tras pulsar el botón Obtener datos</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/primertrace.png" medium="image">
			<media:title type="html">Trace de la página inicial</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/codigo-cache1.png" medium="image">
			<media:title type="html">Código con uso de Cache</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/segundotrace.png" medium="image">
			<media:title type="html">Trace de la página utilizando la Cache</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/obtenerdatos2.png" medium="image">
			<media:title type="html">Método ObtenerDatos modificado</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/modificararchivo.png" medium="image">
			<media:title type="html">Método modificarArchivoXml.</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/diseno2.png" medium="image">
			<media:title type="html">Diseño de la página</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/trace2sincache.png" medium="image">
			<media:title type="html">trace2sincache</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/trace2concache.png" medium="image">
			<media:title type="html">trace2concache</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/trace2nuevafila.png" medium="image">
			<media:title type="html">trace2nuevafila</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/trace2connuevafila.png" medium="image">
			<media:title type="html">trace2connuevafila</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/sqlcachewebconfig1.png" medium="image">
			<media:title type="html">sqlcachewebconfig</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/obtenerdatos3.png" medium="image">
			<media:title type="html">obtenerdatos3</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/artistas.png" medium="image">
			<media:title type="html">artistas</media:title>
		</media:content>
	</item>
		<item>
		<title>Decorator Pattern (Patrón Decorador)</title>
		<link>http://jimenezroda.wordpress.com/2009/08/07/decorator-pattern-patron-decorador/</link>
		<comments>http://jimenezroda.wordpress.com/2009/08/07/decorator-pattern-patron-decorador/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 11:34:38 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[Patterns and Practices]]></category>
		<category><![CDATA[Decorator Pattern]]></category>
		<category><![CDATA[Ingeniería del Software]]></category>
		<category><![CDATA[Patterns & Practices]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=185</guid>
		<description><![CDATA[Continuando con la temática de patrones de diseño software, hoy me propongo explicar el patrón Decorador. En ocasiones, durante la etapa de creación del diseño lógico de nuestra aplicación, podemos encontrarnos que necesitamos poder extender la funcionalidad de una clase en tiempo de ejecución. Tambien podemos encontrarnos en la tesitura de necesitar que cierta funcionalidad [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=185&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Continuando con la temática de patrones de diseño software, hoy me propongo explicar el patrón Decorador.<br />
En ocasiones, durante la etapa de creación del diseño lógico de nuestra aplicación, podemos encontrarnos que necesitamos poder extender la funcionalidad de una clase en tiempo de ejecución.<br />
Tambien podemos encontrarnos en la tesitura de necesitar que cierta funcionalidad pueda ser &#8220;asociada&#8221; a diferentes componentes. Es en estos contextos donde el patrón <em>Decorador </em>puede salvarnos!<span id="more-185"></span></p>
<p>Un ejemplo muy utilizado para explicar éste patrón es el ejemplo de una <span style="text-decoration:underline;">Ventana del sistema</span>. Podemos tener ventanas sin borde, con borde, ventanas que proporcionen un icono con ayuda, ventanas que proporcionen un botón para minimizar a la barra de notificaciones, etc..<br />
Bien, uno podría pensar en crear una clase base llamada <em>Ventana</em> con las funcionalidades básicas de este objeto. Al necesitar una ventana con bordes, podríamos pensar en crear una clase llamada <em>VentanaConBorde</em> que herede de la clase <em>Ventana</em>. Hasta aquí perfecto. Ahora necesitamos tambien una ventana que contenga un icono de ayuda. Volveríamos a heredar de <em>Ventana</em> para crear la clase <em>VentanaConIcono</em>. Pero claro, yo quiero tener una ventan con borde e icono. Asi pues tambien debo crear otra clase que herede de <em>VentanaConBorde</em> y que tenga el icono. Esta clase se podría llamar <em>VentanaConBordeEIcono</em>. Una vez hecho esto, nos damos cuenta de que tambien podemos crear ventanas con un botón que minimice a la barra de notificaciones, pero claro pueden ser ventanas con o sin borde y con o sin icono de ayuda (con todas sus combinaciones).</p>
<p>Nos podemos dar cuenta de que con la herencia de objetos no podremos solucionar (de una forma simple y mantenible) este problema. Aquí es donde el patrón <em>Decorador</em> nos ayudará.</p>
<p>Para empezar, éste es el esquema de la solución que propone este patrón:</p>
<div id="attachment_187" class="wp-caption aligncenter" style="width: 310px"><img class="size-medium wp-image-187" title="Diagrama de clases UML para el patrón Decorador" src="http://jimenezroda.files.wordpress.com/2009/08/757px-decorator_uml_class_diagram-svg.png?w=300&#038;h=237" alt="Muestra las clases que aplican al patrón y las relaciones existentes entre ellas" width="300" height="237" /><p class="wp-caption-text">Muestra las clases que aplican al patrón Decorador y las relaciones existentes entre ellas</p></div>
<p><span style="color:#333399;"><span style="text-decoration:underline;">Descripción de los elementos del diagrama:</span></span></p>
<p><strong><em><span style="color:#333333;">Component:</span></em></strong><span style="color:#333333;"> es una clase abstracta que englobará cualquier elemento que puede ser decorado (en el ejemplo anterior, sería una clase AbstractVentana que incluiría los métodos que definien la interfaz para dibujar los elementos).</span></p>
<p><strong><em>ConcreteComponent:</em></strong> clase que hereda de <em>Component</em> y que define un elemento que puede ser decorado (la clase <em>Component</em> es abstracta, por lo que no puede instanciarse). Es clase implementará las operaciones de la clase <em>Component</em> dando una primera funcionalida base (en el ejemplo anterior, correspondería con la clase <em>Ventana</em>, y el método dibujaría una ventana básica, sin bordes ni nada parecido).</p>
<p><strong><em>Decorator</em></strong>: es la clase base para cualquier decorador que vayamos a utilizar. Se trata de una clase abstracta que será agregada (las clases que la hereden) a cada componente (en el ejemplo, sería una clase <em>AbstractDecorator</em> que no implementaría los métodos de la base, pero que tendría como atributo el componente al que se está aplicando (a nivel de instancia)).</p>
<p><strong><em>ConcreteDecorator</em></strong>:<strong><em> </em></strong>se trata de una clase que hereda de <em>Decorator</em> y que define una funcionalidad concreta a añadir al componente (en el ejemplo podría ser añadir un borde, un icono o un botón. Cada una de ellas sería una clase que deriva de <em>Decorator</em> y que puede asociarse a cualquier <em>Ventana</em>).</p>
<h3><span style="color:#003366;">Un ejemplo práctico</span></h3>
<p><span style="color:#333333;">Con tal de que el patrón quede claro, voy a mostrar un pequeño ejemplo de código en el que utilizo este patrón.</span></p>
<p><span style="color:#333333;">El ejemplo que voy a desarrollar se trata de elaborar iconos a los que se les pueda añadir otros iconos informando de detalles concretos (por ejemplo, en el sistema operativo Windows Vista, cuando una aplicación requiere de aprobación del Administrador,  su icono está &#8220;decorado&#8221; con otro pequeño icono en forma de escudo en los 4 colores del icono de windows). Viene a ser el mismo ejemplo. Queremos poder decorar ciertos iconos en función de las  características  que se apliquen a ese icono.</span></p>
<div id="attachment_194" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-194" title="Clase AbstractIcon" src="http://jimenezroda.files.wordpress.com/2009/08/abstracticon.png?w=500&#038;h=430" alt="Clase AbstractIcon" width="500" height="430" /><p class="wp-caption-text">Esta clase se corresponde con la clase Component del diagrama de clases UML para el patrón Decorator.</p></div>
<p>En segundo lugar, pasamos a crear la clase <strong><em>AbstractDecorator</em></strong> que será la clase base para todos aquellos decoradores que puedan aplicarse a un icono (en realidad no es más que otro icono que dibujaremos encima del original, en una posición concreta).</p>
<div id="attachment_193" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-193" title="Clase AbstractDecorator" src="http://jimenezroda.files.wordpress.com/2009/08/abstracdecorator.png?w=500&#038;h=625" alt="Esta clase se corresponde con la clase Decorator del diagrama de clases UML del patrón Decorator." width="500" height="625" /><p class="wp-caption-text">Esta clase se corresponde con la clase Decorator del diagrama de clases UML del patrón Decorator.</p></div>
<p>Ahora que ya hemos definido las clases base, podemos crear las clases que heredarán de estas y que serán las que nos proporcionarán toda la funcionalidad. Emepezaremos definiendo un decorador concreto:</p>
<div id="attachment_197" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-197" title="Clase IconDecorator" src="http://jimenezroda.files.wordpress.com/2009/08/icondecorator.png?w=500&#038;h=456" alt="Esta clase se corresponde con la clase ConcreteDecorator del diagrama de clases UML del patrón Decorator." width="500" height="456" /><p class="wp-caption-text">Esta clase se corresponde con la clase ConcreteDecorator del diagrama de clases UML del patrón Decorator.</p></div>
<p>Y ahora una clase que herede de la clase AbstractIcon y que admita decoradores:</p>
<div id="attachment_198" class="wp-caption aligncenter" style="width: 509px"><img class="size-full wp-image-198" title="Clase MyIconClass" src="http://jimenezroda.files.wordpress.com/2009/08/myiconclass.png?w=499&#038;h=698" alt="Esta clase se corresponde con la clase ConcreteComponent del diagrama de clases UML para el patrón Decorator." width="499" height="698" /><p class="wp-caption-text">Esta clase se corresponde con la clase ConcreteComponent del diagrama de clases UML para el patrón Decorator.</p></div>
<p>Por último os dejo el código de un formulario Winform en el que se hace uso de todas estas clases para dibujar un icono al que, al pulsar un botón del formulario, se le añade un decorador.</p>
<p><img class="aligncenter size-full wp-image-195" title="Form 1a Parte" src="http://jimenezroda.files.wordpress.com/2009/08/fomr1.png?w=565&#038;h=536" alt="Form 1a Parte" width="565" height="536" /></p>
<p><img class="aligncenter size-full wp-image-196" title="Form 2a Parte" src="http://jimenezroda.files.wordpress.com/2009/08/from2.png?w=500&#038;h=159" alt="Form 2a Parte" width="500" height="159" />Simplemente remarcar que, por el diseño que hemos realizado, un decorador puede contener otros decoradores, lo que nos proporciona un enorme abanico de posibilidades y combinaciones.</p>
<p>Y eso es todo sobre este patrón. Como veis, en determinadas situaciones puede resultarnosde mucha utilidad, como todos los patrones de diseño.<br />
Como siempre, espero que este artículo os resulte útil e interesante!</p>
<p>¡Hasta otra!</p>
<br /> Tagged: Decorator Pattern, Ingeniería del Software, Patterns &amp; Practices <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/185/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/185/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/185/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/185/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/185/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/185/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/185/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=185&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2009/08/07/decorator-pattern-patron-decorador/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/757px-decorator_uml_class_diagram-svg.png?w=300" medium="image">
			<media:title type="html">Diagrama de clases UML para el patrón Decorador</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/abstracticon.png" medium="image">
			<media:title type="html">Clase AbstractIcon</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/abstracdecorator.png" medium="image">
			<media:title type="html">Clase AbstractDecorator</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/icondecorator.png" medium="image">
			<media:title type="html">Clase IconDecorator</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/myiconclass.png" medium="image">
			<media:title type="html">Clase MyIconClass</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/fomr1.png" medium="image">
			<media:title type="html">Form 1a Parte</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2009/08/from2.png" medium="image">
			<media:title type="html">Form 2a Parte</media:title>
		</media:content>
	</item>
		<item>
		<title>Open Closed Principle</title>
		<link>http://jimenezroda.wordpress.com/2009/08/05/open-closed-principle/</link>
		<comments>http://jimenezroda.wordpress.com/2009/08/05/open-closed-principle/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 19:38:35 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[Patterns and Practices]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Ingeniería del Software]]></category>
		<category><![CDATA[Patterns & Practices]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=136</guid>
		<description><![CDATA[La mayoría de proyectos en los que nos vemos envueltos implican modificar código existente en vez de escribir código nuevo. En la mayoría de éstas ocasiones modificar dicho código resulta un trabajo tedioso. El principio Open Closed nos ayuda a acometer esta tarea de una forma mucho mas simple (siempre y cuando se siga éste [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=136&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>La mayoría de proyectos en los que nos vemos envueltos implican modificar código existente en vez de escribir código nuevo. En la mayoría de éstas ocasiones modificar dicho código resulta un trabajo tedioso. El principio <em>Open Closed </em>nos ayuda a acometer esta tarea de una forma mucho mas simple (siempre y cuando se siga éste principio a la hora de desarrollar nuestros proyectos).<br />
De forma muy breve, se puede resumir éste principio de la siguiente forma:  <em>las entidades software deben estar abiertas a extensiones, pero cerradas a modificaciones.  <span id="more-136"></span></em>Éste principio está fuertemente relacionado con los patrones <a href="http://jimenezroda.wordpress.com/2008/12/15/low-coupling-pattern-patron-bajo-acoplamiento" target="_self"><strong>Bajo acoplamiento</strong> </a>y <strong><a href="http://jimenezroda.wordpress.com/2008/12/15/high-cohesion-pattern-patron-alta-cohesion" target="_self">Alta cohesión</a> </strong>(ambos explicados en sus correspondientes links).<br />
Tal y como comentaba, éste principio nos indica que, (en un mundo ideal) no deberíamos cambiar código existente o clases. Cualquier nueva funcionalidad se puede añadir mediante subclases y sobreescribiendo métodos o bien reutilizando código existente mediante delegación.</p>
<p>Esto evita que introduzcamos nuevos <em>bugs </em>o errores en un código existente. Si nunca lo cambiamos,¡ nunca lo rompemos!</p>
<p>¿Y cómo llevamos a cabo nuestro objetivo?</p>
<p>Pues no hay un método o procedimiento único. Debemos aplicar, en cada contexto, aquellos patrones de diseño que nos permitan preveer posibles actualizaciones o ampliaciones de nuestro código.<br />
<span style="text-decoration:underline;"><strong>Un ejemplo práctico:</strong></span></p>
<p>A continuación os presento un pequeño ejemplo en el que muestro los beneficios de aplicar correctamente los patrones de diseño con tal de cumplir con el principio <em>Open Closed</em>:</p>
<p style="text-align:left;">Este ejemplo muestra una clase llamada <strong><em>Filtro</em></strong> que se utiliza para filtrar los elementos que se le pasan dentro de una colección en función de uno de los atributos o propiedades de dichos elementos. En este ejemplo, la clase filtro filtrará elementos del tipo <strong><em>Persona</em></strong>. La clase persona tiene el siguiente código:</p>
<pre style="text-align:left;"><span style="color:#0000ff;">using </span>System;
<span style="color:#0000ff;">using </span>System.Collections.Generic;
<span style="color:#0000ff;">using </span>System.Linq;
<span style="color:#0000ff;">using </span>System.Text;

<span style="color:#0000ff;">namespace </span>OpenClosedPrinciple
{
<span style="color:#008000;"> <span style="color:#c0c0c0;">   /// </span><span style="color:#c0c0c0;"><span style="color:#c0c0c0;">&lt;summ</span>ary&gt;</span>
    <span style="color:#c0c0c0;">///</span> Clase Persona. Almacena los atributos básicos de una
    <span style="color:#c0c0c0;">///</span> persona. Sirve de ejemplo para mostrar los beneficios
    <span style="color:#c0c0c0;">///</span> de aplicar el principio Open Closed.
    <span style="color:#c0c0c0;">/// </span><span style="color:#c0c0c0;"><span style="color:#c0c0c0;">&lt;/s</span>ummary&gt;</span></span>
    <span style="color:#0000ff;">public </span><span style="color:#0000ff;">class </span><span style="color:#99cc00;">Persona</span>
    {
       #region Class attributes

<span style="color:#008000;">       /// <span style="color:#c0c0c0;">&lt;summary&gt;</span>
       /// Nombre de la persona
       /// <span style="color:#c0c0c0;">&lt;/summary&gt;</span></span>
       <span style="color:#0000ff;">private </span><span style="color:#0000ff;">string </span>_name;

<span style="color:#008000;">       <span style="color:#c0c0c0;">/// &lt;summary&gt;</span>
       <span style="color:#c0c0c0;">///</span> Apellidos de la persona
       <span style="color:#c0c0c0;">/// &lt;/summary&gt;</span></span>
       <span style="color:#0000ff;">private </span><span style="color:#0000ff;">string </span>_secondName;

<span style="color:#008000;">       <span style="color:#c0c0c0;">/// &lt;summary&gt;</span>
<span style="color:#c0c0c0;">       ///</span> Edad de la persona.
       <span style="color:#c0c0c0;">/// &lt;/summary&gt;</span></span>
       <span style="color:#0000ff;">private </span><span style="color:#0000ff;">int </span>_age;

       #endregion

       #region Class constructors

<span style="color:#008000;"><span style="color:#c0c0c0;">       /// &lt;summary&gt;</span>
       <span style="color:#c0c0c0;">///</span> Constructor por defecto de la clase Persona
<span style="color:#c0c0c0;">       /// &lt;/summary&gt;</span></span>
       <span style="color:#0000ff;">public </span>Persona()
       {
       }

<span style="color:#008000;">       <span style="color:#c0c0c0;">/// &lt;summary&gt;</span>
       <span style="color:#c0c0c0;">/// </span>Constructor que recibe como parámetro el nombre de la persona
       <span style="color:#c0c0c0;">/// &lt;/summary&gt;</span>
       <span style="color:#c0c0c0;">/// &lt;param name="name"&gt;</span>Nombre de la persona<span style="color:#c0c0c0;">&lt;/param&gt;</span></span>
       <span style="color:#0000ff;">public </span>Persona(<span style="color:#0000ff;">string </span>name)
       : <span style="color:#0000ff;">this</span>()
       {
          <span style="color:#0000ff;">this</span>._name = name;
       }

<span style="color:#008000;">       <span style="color:#c0c0c0;">/// &lt;summary&gt;</span>
       <span style="color:#c0c0c0;">///</span> Constructor que recibe como parámetro el nombre
       <span style="color:#c0c0c0;">///</span> y el apellido de la persona
 <span style="color:#c0c0c0;">      /// &lt;/summary&gt;
       /// &lt;param name="name"&gt;</span>Nombre de la persona<span style="color:#c0c0c0;">&lt;/param&gt;
       /// &lt;param name="secondName"&gt;</span>Apellido de la persona<span style="color:#c0c0c0;">&lt;/param&gt;</span></span>
       <span style="color:#0000ff;">public </span>Persona(<span style="color:#0000ff;">string </span>name, <span style="color:#0000ff;">string </span>secondName)
       : <span style="color:#0000ff;">this</span>(name)
       {
          <span style="color:#0000ff;">this</span>._secondName = secondName;
       }
<span style="color:#008000;">
       <span style="color:#c0c0c0;">/// &lt;summary&gt;
       /// </span>Constructor que recibe como parámetro el nombre, apellidos y
       <span style="color:#c0c0c0;">///</span> la edad de la persona
       <span style="color:#c0c0c0;">/// </span>&lt;/summary&gt;
       <span style="color:#c0c0c0;">///</span> &lt;param name="name"&gt;Nombre de la persona&lt;/param&gt;
       <span style="color:#c0c0c0;">///</span> &lt;param name="secondName"&gt;Apellido de la persona&lt;/param&gt;
       <span style="color:#c0c0c0;">/// &lt;param name="age"&gt;</span>Edad de la persona<span style="color:#c0c0c0;">&lt;/param&gt;</span></span>
       <span style="color:#0000ff;">public </span>Persona(<span style="color:#0000ff;">string </span>name, <span style="color:#0000ff;">string </span>secondName,int age)
       : <span style="color:#0000ff;">this</span>(name,secondName)
       {
          <span style="color:#0000ff;">this</span>._age = age;
       }

       #endregion

       #region Class public properties

<span style="color:#008000;">       <span style="color:#c0c0c0;">/// &lt;summary&gt;</span>
       <span style="color:#c0c0c0;">///</span> Devuelve o establece la edad de la persona.
       <span style="color:#c0c0c0;">/// &lt;/summary&gt;</span></span>
       <span style="color:#0000ff;">public </span><span style="color:#0000ff;">int </span>Age
       {
          <span style="color:#0000ff;">get</span>
          {
             <span style="color:#0000ff;">return </span>_age;
          }

          <span style="color:#0000ff;">set</span>
          {
            _age = <span style="color:#0000ff;">value</span>;
          }
       }

<span style="color:#008000;"> <span style="color:#c0c0c0;">     /// &lt;summary&gt;</span>
      <span style="color:#c0c0c0;">///</span> Devuelve o establece el nombre de la persona.
      <span style="color:#c0c0c0;">/// &lt;/summary&gt;</span></span>
      <span style="color:#0000ff;">public </span><span style="color:#0000ff;">string </span>Name
      {
         <span style="color:#0000ff;">get</span>
         {
            <span style="color:#0000ff;">return </span>_name;
         }

         <span style="color:#0000ff;">set</span>
         {
            _name = <span style="color:#0000ff;">value</span>;
         }
      }

<span style="color:#008000;">      <span style="color:#c0c0c0;">/// &lt;summary&gt;</span>
      <span style="color:#c0c0c0;">///</span> Devuelve o establece el apellido de la persona.
      <span style="color:#c0c0c0;">/// &lt;/summary&gt;</span></span>
      <span style="color:#0000ff;">public </span><span style="color:#0000ff;">string </span>SecondName
      {
         <span style="color:#0000ff;">get</span>
         {
            <span style="color:#0000ff;">return </span>_secondName;
         }

         <span style="color:#0000ff;">set</span>
         {
           _secondName = <span style="color:#0000ff;">value</span>;
         }
      }

      #endregion
   }
}</pre>
<p>Una vez definida la clase que se deberá filtrar (es decir, recibiremos una lista de personas y deberemos filtrar por alguno de sus atributos o propiedades, por ejemplo, filtrar por nombre o por apellidos) ahora podemos pasar a definir la clase que se encargará de filtrar los elementos que recibirá como parámetro. A esta clase la hemos llamado <strong><em>Filtro</em></strong>.</p>
<p>En esta primera muestra de código no utilizaré ningún patrón, por lo que no cumpliremos con el principio, como veremos más adelante:</p>
<pre><span style="color:#0000ff;">using </span>System;
<span style="color:#0000ff;">using </span>System.Collections.Generic;
<span style="color:#0000ff;">using </span>System.Linq;
<span style="color:#0000ff;">using </span>System.Text;

<span style="color:#0000ff;">namespace </span>OpenClosedPrinciple
{
    <span style="color:#888888;">/// &lt;summary&gt;</span>
 <span style="color:#888888;">   ///</span> <span style="color:#008000;">Clase filtro. Filtra objetos en base a un atributo de los elementos</span>
    <span style="color:#888888;">///</span> <span style="color:#008000;">y a un parámetro de entrada.</span>
<span style="color:#888888;">    /// &lt;/summary&gt;</span>
 <span style="color:#0000ff;">   public </span><span style="color:#0000ff;">class </span><span style="color:#99cc00;">Filtro</span>
    {
<span style="color:#888888;">       /// &lt;summary&gt;</span>
 <span style="color:#888888;">      ///</span> <span style="color:#008000;">Método que filtra un enumerado de personas en base a su nombre.</span>
       <span style="color:#888888;">/// &lt;/summary&gt;</span>
 <span style="color:#0000ff;">      public </span><span style="color:#99cc00;">IEnumerable&lt;Persona&gt;</span> Filtrar(<span style="color:#99cc00;">IEnumerable&lt;Persona&gt;</span> personas, <span style="color:#0000ff;">string </span>nombre)
       {
          <span style="color:#0000ff;">foreach </span>(<span style="color:#0000ff;">var </span>Persona <span style="color:#0000ff;">in </span>personas)
          {
              <span style="color:#0000ff;">if </span>(Persona.Name.Equals(nombre))
 <span style="color:#0000ff;">                yield return</span> Persona;
          }
       }
    }
}</pre>
<p>Esta clase funciona perfectamente. De hecho, a simple vista, nadie diría que tenga que tocarse en un futuro. Pero la verdad es otra y, muy seguramente, en un futuro nos pedirían que se pueda filtrar las personas por su apellido. Esto implica que tenemos que &#8220;<em><strong>abrir</strong></em>&#8221; la clase, cambiar el código y luego volver a compilar y distribuir. Entonces tendríamos algo tal que así:</p>
<pre><span style="color:#0000ff;">using </span>System;
<span style="color:#0000ff;">using </span>System.Collections.Generic;
<span style="color:#0000ff;">using </span>System.Linq;
<span style="color:#0000ff;">using </span>System.Text;

<span style="color:#0000ff;">namespace </span>OpenClosedPrinciple
{
    <span style="color:#888888;">/// &lt;summary&gt;</span>
 <span style="color:#888888;">   ///</span> <span style="color:#008000;">Clase filtro. Filtra objetos en base a un atributo de los elementos</span>
    <span style="color:#888888;">///</span> <span style="color:#008000;">y a un parámetro de entrada.</span>
<span style="color:#888888;">    /// &lt;/summary&gt;</span>
 <span style="color:#0000ff;">   public </span><span style="color:#0000ff;">class </span><span style="color:#99cc00;">Filtro</span>
    {
<span style="color:#888888;">       /// &lt;summary&gt;</span>
 <span style="color:#888888;">      ///</span> <span style="color:#008000;">Método que filtra un enumerado de personas en base a su nombre.</span>
       <span style="color:#888888;">/// &lt;/summary&gt;</span>
 <span style="color:#0000ff;">      public </span><span style="color:#99cc00;">IEnumerable&lt;Persona&gt;</span> Filtrar(<span style="color:#99cc00;">IEnumerable&lt;Persona&gt;</span> personas, <span style="color:#0000ff;">string </span>nombre)
       {
          <span style="color:#0000ff;">foreach </span>(<span style="color:#0000ff;">var </span>Persona <span style="color:#0000ff;">in </span>personas)
          {
              <span style="color:#0000ff;">if </span>(Persona.Name.Equals(nombre))
 <span style="color:#0000ff;">                yield return</span> Persona;
          }
       }

       <span style="color:#0000ff;">public </span><span style="color:#99cc00;">IEnumerable&lt;Persona&gt;</span> FiltrarApellidos(<span style="color:#99cc00;">IEnumerable&lt;Persona&gt;</span> personas, <span style="color:#0000ff;">string </span>apellido)
       {
          <span style="color:#0000ff;">foreach </span>(<span style="color:#0000ff;">var </span>Persona <span style="color:#0000ff;">in </span>personas)
          {
              if (Personas.Apellido.Equals(apellido))
                 <span style="color:#0000ff;">yield return</span> Persona;
          }
       }
    }
}</pre>
<p>Bueno, no tiene mala pinta, pero, como ya he comentado, hemos tenido que abrir el código, cambiarlo, recompilar y redistribuir de nuevo. Si es sólo por esta vez podríamos aceptarlo, pero ahora viene cuando alguien decide que también debemos filtrar por la edad de la persona. ¿Y que implica eso? Pues volver a abrir, cambiar el código, volver a recompilar y volver a distribuir.<br />
Como podeis ver, no es la mejor de las opciones. Lo que nos indica el principio <em>Open Closed</em> es que la clase Filtro debería quedar cerrada, lo que indica que no deberíamos volver a tocarla. Cualquier nueva funcionalidad la tendríamos que implementar o bien en clases derivadas y sobreescribiendo métodos o bien mediante la delegación de métodos.</p>
<p>La solución, aplicar patrones de diseño o una buena guia de diseño como la que vamos a aplicar&#8230;&#8221;Encapsular todo aquello que cambia&#8221;.</p>
<p>Asi pues, modificaremos el código para que quede de la siguiente forma. Crearemos una interfaz llamada <strong>IElemento</strong>. Todo elemento (objeto) que pueda ser filtrado, deberá heredar de <strong>IElemento</strong>.</p>
<pre><span style="color:#0000ff;">using </span>System;
<span style="color:#0000ff;">using </span>System.Collections.Generic;
<span style="color:#0000ff;">using </span>System.Linq;
<span style="color:#0000ff;">using </span>System.Text;

<span style="color:#0000ff;">namespace </span>OpenClosedPrinciple
{
    <span style="color:#0000ff;">interface </span><span style="color:#99cc00;">IElemento</span>
    {
    }
}</pre>
<p>Crearemos una interfaz llamada <strong>IComparacion </strong>que será una interfaz genérica y que tendrá un método que nos permita comparar un atributo interno con un elemento del tipo de la interfaz. Esta interfaz deberá ser implementada por aquellas clases que sirvan como comparador a la hora de aplicar un filtro. Por decirlo de alguna forma, la clase que implemente esta interfaz  será la encargada de determinar si un elemento de la lista de elementos totales estará en el resultado o no.</p>
<pre><span style="color:#0000ff;">using </span>System;
<span style="color:#0000ff;">using </span>System.Collections.Generic;
<span style="color:#0000ff;">using </span>System.Linq;
<span style="color:#0000ff;">using </span>System.Text;

<span style="color:#0000ff;">namespace </span>OpenClosedPrinciple
{
    <span style="color:#0000ff;">interface </span><span style="color:#99cc00;">IComparacion</span>&lt;T&gt;
    {
          <span style="color:#0000ff;">bool </span>CompararCon(T item);
    }
}</pre>
<p>Seguidamente, definiremos la interfaz <strong><em>IFiltro</em></strong>. Esta interfaz permitirá definir distintos filtros en función de la comparación y los elementos a comparar. La clase que implemente esta interfaz será la que se encargará de controlar el proceso de filtrado.</p>
<pre><span style="color:#0000ff;">using </span>System;
<span style="color:#0000ff;">using </span>System.Collections.Generic;
<span style="color:#0000ff;">using </span>System.Linq;
<span style="color:#0000ff;">using </span>System.Text;

<span style="color:#0000ff;">namespace </span>OpenClosedPrinciple
{
    <span style="color:#0000ff;">interface </span><span style="color:#99cc00;">IFiltro</span>&lt;typodefiltro&gt;
    {
         <span style="color:#99cc00;">IEnumerable</span>&lt;typodefiltro&gt; Filtrar(<span style="color:#99cc00;">IEnumerable</span>&lt;typodefiltro&gt; elementos, <span style="color:#99cc00;">IComparacion</span>&lt;typodefiltro&gt; comparacion);
    }
}</pre>
<p>Como puede observarse esta interfaz es genérica y permite definir el tipo de filtro a aplicar. El tipo de filtro nos indicará el tipo de elementos que contendrá la lista de elementos asi como el tipo de objeto que la comparación utiliza para filtrar.<br />
Una vez definidas las interfaces, pasaremos a definir las clases que las implementan. La primera será la clase <strong>Persona </strong>(tal y como la definimos antes). El único cambio en esta clase es que ahora implementa la interfaz <strong>IElemento</strong>:</p>
<pre style="text-align:left;"><span style="color:#0000ff;">using </span>System;
<span style="color:#0000ff;">using </span>System.Collections.Generic;
<span style="color:#0000ff;">using </span>System.Linq;
<span style="color:#0000ff;">using </span>System.Text;

<span style="color:#0000ff;">namespace </span>OpenClosedPrinciple
{
<span style="color:#008000;"> <span style="color:#c0c0c0;">   /// </span><span style="color:#c0c0c0;"><span style="color:#c0c0c0;">&lt;summ</span>ary&gt;</span>
    <span style="color:#c0c0c0;">///</span> Clase Persona. Almacena los atributos básicos de una
    <span style="color:#c0c0c0;">///</span> persona. Sirve de ejemplo para mostrar los beneficios
    <span style="color:#c0c0c0;">///</span> de aplicar el principio Open Closed.
    <span style="color:#c0c0c0;">/// </span><span style="color:#c0c0c0;"><span style="color:#c0c0c0;">&lt;/s</span>ummary&gt;</span></span>
    <span style="color:#0000ff;">public </span><span style="color:#0000ff;">class </span><span style="color:#99cc00;">Persona</span>:<span style="color:#99cc00;">IElemento</span>
    {
       #region Class attributes
    ...
}</pre>
<p>El siguiente paso será crear una clase que implemente la interfaz <strong>IComparacion</strong>. Crearemos una clase que, tal y como se hacía en el ejemplo original, filtre las personas por su nombre. La clase se llamará <strong>ComparacionPersonaNombre</strong>.</p>
<pre><span style="color:#0000ff;">using </span>System;
<span style="color:#0000ff;">using </span>System.Collections.Generic;
<span style="color:#0000ff;">using </span>System.Linq;
<span style="color:#0000ff;">using </span>System.Text;

<span style="color:#0000ff;">namespace </span>OpenClosedPrinciple
{
    <span style="color:#0000ff;">class </span><span style="color:#99cc00;">CompararPersonaNombre</span>:<span style="color:#99cc00;">IComparacion</span>&lt;<span style="color:#99cc00;">IElemento</span>&gt;
    {
          private string nombre;

        <span style="color:#0000ff;"> #region</span> Miembros de IComparacion&lt;string&gt;

         <span style="color:#0000ff;">public </span><span style="color:#0000ff;">bool </span>CompararCon(<span style="color:#99cc00;">IElemento </span>item)
        {
              <span style="color:#0000ff;">return </span>nombre.Equals(((<span style="color:#99cc00;">Persona</span>)item).Name);
        }

       <span style="color:#0000ff;">#endregion</span>

       <span style="color:#0000ff;">public </span>CompararPersonaNombre(<span style="color:#0000ff;">string </span>nombre)
       {
             <span style="color:#0000ff;">this</span>.nombre = nombre;
       }
   }
}</pre>
<p>Esta clase recibe como parámetro un nombre con el que se quiere comparar el elemento que recibe como parámetro el método CompararCon (método definido en la interfaz). Como queremos comparar un nombre con el nombre de una Persona, lo que haces es un cast al objeto item para obtener el nombre de la persona.</p>
<p>Lo último que nos queda por hacer es definir la clase <strong>Filtro</strong>, que implementará la interfaz <em>IFiltro</em> y que será la encargada de controlar todo el filtrado.</p>
<pre><span style="color:#0000ff;">using </span>System;
<span style="color:#0000ff;">using </span>System.Collections.Generic;
<span style="color:#0000ff;">using </span>System.Linq;
<span style="color:#0000ff;">using </span>System.Text;

<span style="color:#0000ff;">namespace </span>OpenClosedPrinciple
{
      <span style="color:#0000ff;">class </span><span style="color:#99cc00;">Filtro</span>:<span style="color:#99cc00;">IFiltro</span>&lt;<span style="color:#99cc00;">IElemento</span>&gt;
      {
         <span style="color:#0000ff;">#region</span> Miembros de IFiltro&lt;IElemento&gt;

         <span style="color:#0000ff;">public </span><span style="color:#99cc00;">IEnumerable</span>&lt;<span style="color:#99cc00;">IElemento</span>&gt; Filtrar(<span style="color:#99cc00;">IEnumerable</span>&lt;<span style="color:#99cc00;">IElemento</span>&gt; elementos, <span style="color:#99cc00;">IComparacion</span>&lt;<span style="color:#99cc00;">IElemento</span>&gt; comparacion)
         {
             <span style="color:#0000ff;">foreach </span>(<span style="color:#0000ff;">var </span>elemento <span style="color:#0000ff;">in </span>elementos)
             {
                <span style="color:#0000ff;">if</span>(comparacion.CompararCon(elemento))
                   <span style="color:#0000ff;">yield </span><span style="color:#0000ff;">return </span>elemento;
             }
         }

         <span style="color:#0000ff;">#endregion</span>
     }
}</pre>
<p>Como puede verse, en la implementación del método Filtrar, lo que se hace es recorrer la lista de elementos y aplicar a cada elemento la comparación. Si es válida se añade el elemento a la lista de resultados.</p>
<p>Y con esto ya está todo. Si, es evidente que no es tan simple como antes. No es complicado, digamos que no es trivial. Pero el diseño es mucho más limpio, más cohesionado, menos acoplado y mucho más mantenible.</p>
<p>Por último muestro una pequeña aplicación de tipo Consola que hace uso de todo esto:</p>
<pre><span style="color:#0000ff;">using </span>System;
<span style="color:#0000ff;">using </span>System.Collections.Generic;
<span style="color:#0000ff;">using </span>System.Linq;
<span style="color:#0000ff;">using </span>System.Text;
<span style="color:#0000ff;">using </span>System.Collections;

<span style="color:#0000ff;">namespace </span>OpenClosedPrinciple
{
    <span style="color:#0000ff;">class </span>Program
    {
      <span style="color:#0000ff;">static </span><span style="color:#0000ff;">void </span>Main(<span style="color:#0000ff;">string</span>[] args)
      {
 <span style="color:#008000;">          //Creamos una lista de personas.</span>
           <span style="color:#99cc00;">IEnumerable</span>&lt;<span style="color:#99cc00;">IElemento</span>&gt; personas = listaPersonas();

           <span style="color:#008000;">//Creamos una comparación por nombre para filtrar las personas
           //por aquellas que se llamen "j"</span>
           <span style="color:#99cc00;">CompararPersonaNombre </span>compararNombre = <span style="color:#0000ff;">new </span><span style="color:#99cc00;">CompararPersonaNombre</span>(<span style="color:#993366;">"j"</span>);

          <span style="color:#008000;"> //Creamos el objeto filtro que va a filtrar la lista de personas</span>
          <span style="color:#99cc00;"> Filtro </span>filtro = new <span style="color:#99cc00;">Filtro</span>();

          <span style="color:#99cc00;"> IEnumerable</span>&lt;<span style="color:#99cc00;">IElemento</span>&gt; filtradas = filtro.Filtrar(personas, compararNombre);

          <span style="color:#008000;"> //Mostramos el resultado</span>
           <span style="color:#0000ff;">foreach </span>(<span style="color:#99cc00;">Persona </span>persona <span style="color:#0000ff;">in </span>filtradas)
           {
             <span style="color:#99cc00;">Console</span>.WriteLine(persona.Name);
           }
<span style="color:#99cc00;">           Console</span>.ReadKey();
      }

      <span style="color:#0000ff;">private </span><span style="color:#0000ff;">static </span><span style="color:#99cc00;">IEnumerable</span>&lt;<span style="color:#99cc00;">IElemento</span>&gt; listaPersonas()
      {
          <span style="color:#0000ff;">yield return new</span> Persona(<span style="color:#993366;">"j"</span>, <span style="color:#993366;">"j"</span>, 25);
          <span style="color:#0000ff;">yield return new</span> Persona(<span style="color:#993366;">"p"</span>, <span style="color:#993366;">"p"</span>, 35);
          <span style="color:#0000ff;">yield return new</span> Persona(<span style="color:#993366;">"k"</span>, <span style="color:#993366;">"k"</span>, 45);
          <span style="color:#0000ff;">yield return new</span> Persona(<span style="color:#993366;">"h"</span>, <span style="color:#993366;">"j"</span>, 15);
      }
   }
}</pre>
<p>Y eso es todo acerca de este principio. Espero que os resulte interesante y, sobretodo, útil.</p>
<p>Gracias a todos!</p>
<br /> Tagged: .NET, Ingeniería del Software, Patterns &amp; Practices <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/136/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=136&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2009/08/05/open-closed-principle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>
	</item>
		<item>
		<title>High cohesion pattern (Patrón alta cohesión)</title>
		<link>http://jimenezroda.wordpress.com/2008/12/18/high-cohesion-pattern-patron-alta-cohesion/</link>
		<comments>http://jimenezroda.wordpress.com/2008/12/18/high-cohesion-pattern-patron-alta-cohesion/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 11:03:38 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[Patterns and Practices]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Ingeniería del Software]]></category>
		<category><![CDATA[Patterns & Practices]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=145</guid>
		<description><![CDATA[El patrón alta cohesión se aplica en conjunción con el patrón bajo acoplamiento (en realidad son patrones complementarios que siempre deberían aplicarse conjuntamente). El patrón alta cohesión nos indica que los datos y responsabilidades de una entidad están fuertemente ligados a la misma, en un sentido lógico. En otras palabras, la información que maneja una [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=145&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">El patrón <em>alta cohesión</em> se aplica en conjunción con el patrón <em>bajo acoplamiento</em> (en realidad son patrones complementarios que siempre deberían aplicarse conjuntamente). El patrón <em>alta cohesión</em> nos indica que los datos y responsabilidades de una entidad están fuertemente ligados a la misma, en un sentido lógico. En otras palabras, la información que maneja una entidad software debe estar fuertemente ligada a lo que la entidad software representa lógicamente. Pongamos un ejemplo para aclarar el concepto:<span id="more-145"></span></span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">Imaginemos que vamos a desarrollar la clase <span style="text-decoration:underline;">Persona</span> y nos planteamos determinar cuáles son las responsabilidades y la información que debemos asignarle. En este momento debemos razonar de la siguiente forma con tal de aplicar el patrón <em><span>alta cohesión</span>: la información que contenga la clase Persona debe estar relacionada con la entidad que se intenta representar, es decir, una clase Persona (entidad lógica) sólo debe contener información y responsabilidades referentes a una Persona (física).</em>Así pues, podríamos asignar como atributo de la clase Persona los atributos siguientes:</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Nombre</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Apellidos</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Año de Nacimiento</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Peso</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Estatura</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Estado civil</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Color del cabello</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Color de ojos</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Sexo</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">Pero no podemos asignar estos otros, puesto que es información no referente a una Persona:</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Código postal</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Demarcación</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Regalo</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Asignaturas</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Clase </span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">Asimismo, a la hora de asignar las responsabilidades de la clase Persona, deberíamos plantearnos la misma pregunta: ¿es responsabilidad de esta clase?</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">Otro ejemplo:</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">La clase Persona puede tener las siguientes responsabilidades (o métodos):</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- EstablecerNombre</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- EstablecerApellidos</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- Edad</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- AsignarPareja</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">Pero no sería lógico que tuviera una de las siguientes:</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- EstablecerCodigoPostal</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- CalcularNomina</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">- AsignarClase</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">-EnviarRegalo</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">Si cumplimos este pequeño patrón, obtendremos clases que son fácilmente mantenibles y reutilizables lo cual hará nuestro código y nuestra vida más simples.</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">Resumiendo: Una entidad debe tener relacionados aquellos datos y responsabilidades que tengan lógica en la vida real. Para saber si un dato o responsabilidad debe ser asignada a una clase, además de consultar patrones tales como Experto en Información, Patrón Creador, etc.. podríamos intentar relacionar el atributo que estamos intentando asignar con el nombre de la clase. Por ejemplo: la relación entre Persona y Demarcación no parece demasiado obvia. Sin embargo la relación entre Jugador y Demarcación ya nos resulta más lógica (Jugador puede ser una clase que deriva de Persona, con lo que ya lo tendríamos todo relacionado).</span></p>
<p class="MsoNormal" style="margin:6pt 0 6pt 13.05pt;"><span style="font-size:10pt;color:black;font-family:Verdana;">Y eso es todo! Nos vemos pronto por aquí! <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </span></p>
<br /> Tagged: .NET, Ingeniería del Software, Patterns &amp; Practices <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/145/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=145&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2008/12/18/high-cohesion-pattern-patron-alta-cohesion/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>
	</item>
		<item>
		<title>Low coupling pattern (Patrón bajo acoplamiento)</title>
		<link>http://jimenezroda.wordpress.com/2008/12/16/low-coupling-pattern-patron-bajo-acoplamiento/</link>
		<comments>http://jimenezroda.wordpress.com/2008/12/16/low-coupling-pattern-patron-bajo-acoplamiento/#comments</comments>
		<pubDate>Tue, 16 Dec 2008 08:59:31 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[Patterns and Practices]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Ingeniería del Software]]></category>
		<category><![CDATA[Patterns & Practices]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=143</guid>
		<description><![CDATA[Con éste inicio una serie de artículos dedicados a los patrones de diseño software más útiles, conocidos y comunes.  Empiezo con uno, según mi opinión,  de los más importantes (conjuntamente con el patrón alta cohesión). Ambos patrones nos permiten diseñar aplicaciones en las cuales las responsabilidades están correctamente distribuidas, permitiendo un fácil mantenimiento y extensibilidad [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=143&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><span style="font-size:7.5pt;color:black;font-family:Verdana;">Con éste inicio una serie de artículos dedicados a los patrones de diseño software más útiles, conocidos y comunes.  Empiezo con uno, según mi opinión,<span>  </span>de los más importantes (conjuntamente con el patrón a<strong><span style="font-family:Verdana;">lta cohesión</span></strong>). Ambos patrones nos permiten diseñar aplicaciones en las cuales las responsabilidades están correctamente distribuidas, permitiendo un fácil mantenimiento y extensibilidad del software. <span id="more-143"></span></span></p>
<p><span style="font-size:7.5pt;color:black;font-family:Verdana;">Podemos definir el <em><span style="font-family:Verdana;">acoplamiento software</span></em> como el número de relaciones que una entidad software (una clase, por ejemplo) tiene con otras entidades software o, dicho de otra forma, el número de relaciones fuertes (<em>strong relations</em>) que tiene una clase.<br />
Para aclarar el concepto, fijémosnos en las siguientes figuras:</span></p>
<p style="padding-left:120px;"><img class="alignnone size-full wp-image-151" title="coupled class" src="http://jimenezroda.files.wordpress.com/2008/12/coupled.jpg?w=439&#038;h=354" alt="coupled class" width="439" height="354" /> </p>
<p style="padding-left:30px;"><span style="font-size:7.5pt;color:black;font-family:Verdana;">La primera de ellas nos muestra una clase fuertemente acoplada. Como puede observarse, la clase <strong><span style="font-family:Verdana;">A</span></strong> tiene relaciones con las clases B, C, D, E y F. En este caso diríamos que la clase A es una clase con un alto acoplamiento.</span></p>
<p style="padding-left:120px;"> <img class="aligncenter size-full wp-image-153" title="uncoupled" src="http://jimenezroda.files.wordpress.com/2008/12/uncoupled.jpg?w=407&#038;h=378" alt="uncoupled" width="407" height="378" /></p>
<p style="padding-left:30px;"><span style="font-size:7.5pt;color:black;font-family:Verdana;">La segunda imagen nos muestra una clase <strong><span style="font-family:Verdana;">A</span></strong> con un bajo acoplamiento, ya que tiene muy pocas relaciones fuertes con otras entidades.</span></p>
<p><span style="font-size:7.5pt;color:black;font-family:Verdana;">Ahora que el concepto de acoplamiento está definido, podemos realizarnos la pregunta de cómo afecta el acoplamiento a nuestro desarrollo software. A la vista de los diagramas mostrados anteriormente queda claro que, si en cualquier momento es necesario modificar alguna funcionalidad de la clase A, en el caso de que se encuentre fuertemente acoplada es más que probable que nos veamos obligados a modificar alguna de las clases con las que se encuentra relacionada, lo que hace que la modificación de la clase sea más dificultosa.<br />
Sin embargo, si nos encontramos en el contexto de la segunda imagen, la modificación de la clase A será, seguro, mucho más simple.<br />
El patrón bajo acoplamiento, bien aplicado, permite que nuestras entidades software sean más mantenibles, extensibles y reutilizables, ya que tienen perfectamente definidas las responsabilidades y eso permite que puedan ser reutilizadas en cualquier otro contexto, siempre que la funcionalidad que se les demande sea la misma.</span></p>
<p><span style="font-size:7.5pt;color:black;font-family:Verdana;">En definitiva, el patrón bajo acoplamiento nos indica que debemos asignar correctamente las responsabilidades de cada entidad de forma que cada una de éstas tiene asignadas únicamente las responsabilidades que puede llevar a cabo con los datos que ésta tiene disponibles. </span></p>
<p><span style="font-size:7.5pt;color:black;font-family:Verdana;">Como siempre, espero que os sea de utilidad y os resulte interesante. Hasta Pronto! <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </span></p>
<p style="padding-left:30px;"> </p>
<br /> Tagged: .NET, Ingeniería del Software, Patterns &amp; Practices <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/143/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=143&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2008/12/16/low-coupling-pattern-patron-bajo-acoplamiento/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/12/coupled.jpg" medium="image">
			<media:title type="html">coupled class</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/12/uncoupled.jpg" medium="image">
			<media:title type="html">uncoupled</media:title>
		</media:content>
	</item>
		<item>
		<title>Lambda expressions (Expresiones Lambda)</title>
		<link>http://jimenezroda.wordpress.com/2008/11/13/lambda-expressions-expresiones-lambda/</link>
		<comments>http://jimenezroda.wordpress.com/2008/11/13/lambda-expressions-expresiones-lambda/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 21:13:55 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[Novedades .NET Framework 3.5]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Lambda]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=129</guid>
		<description><![CDATA[C# 3.0 incluye una nueva característica llamada expresiones Lambda. Las expresiones lambda son los fundamentos sobre los que se constuye LINQ. Estas provienen del paradigma de programación funcional. En el mundo de la programación funcional, las expresiones lambda son un mecanimos para definir métodosTal y como comenta elGuille, las expresiones lambda facilitan la metaprogramación (es [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=129&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>C# 3.0 incluye una nueva característica llamada <em>expresiones Lambda</em>. Las expresiones lambda son los fundamentos sobre los que se constuye LINQ. Estas provienen del paradigma de programación funcional. En el mundo de la programación funcional, las expresiones lambda son un mecanimos para definir métodos<span id="more-129"></span>Tal y como comenta elGuille, las expresiones lambda facilitan la <span style="text-decoration:underline;">metaprogramación</span> (es decir, programas que controlan otro programas). </p>
<p>Las expresiones lambda pueden considerarse una extensión de los métodos anónimos. Una de las características que más valoran los arquitectos .NET es que una expresión lambda tanto puede ser invocada como utilizada como un dato corriente.<br />
Para implementar expresiones lambda en C# es necesario hacer uso de <strong>delegados</strong>.<br />
La sintaxi para crear expresiones lambda es la siguiente en C#:</p>
<p style="padding-left:30px;"><span style="color:#0000ff;">delegate</span> T <span style="color:#339966;">NombreDelegado</span>&lt;T&gt;(&#8211;parametros&#8211;);</p>
<p>A bote pronto, esto parece chino. Pero podemos empezar a desgranar esta expresión. En realidad se está declarando un <em>delegado genérico</em> que devolverá como valor un objeto del tipo T que es el mismo tipo que trata en su interior. T puede ser cualquier tipo de objeto. Ejemplo:</p>
<p style="padding-left:30px;"><span style="color:#0000ff;">delegate</span> T <span style="color:#008080;">MiFuncion</span>&lt;T&gt;(T x); &#8211;&gt; Primero declaramos el delegado que mapea la función.</p>
<p style="padding-left:30px;"><span style="color:#008080;">MiFuncion</span>&lt;<span style="color:#0000ff;">int</span>&gt;cuadrado= x =&gt;x*x; &#8211;&gt; Especificamos la función lambda.</p>
<p>Podriamos leer la segunda linea como:</p>
<p style="padding-left:30px;">Se define una función llamada cuadrado que devolverá un valor entero y que, dado un valor &#8216;x&#8217; devuelve el valor &#8216;x&#8217; multiplicado por &#8216;x&#8217;. </p>
<p>Para nuestro caso, y para el 90% de los casos, será más útil y recomendable utilizar el <em>tipo genérico predefinido</em> <strong>Func</strong> y cualquiera de sus sobrecargas. De forma que el mismo ejemplo anterior quedaría como:</p>
<p style="padding-left:30px;"><span style="color:#008080;">Func</span>&lt;<span style="color:#0000ff;">int</span>&gt; cuadrado = x =&gt; x*x;</p>
<p>Podríamos utilizar esta expresión lambda como parámetro de una función, de la misma forma que pasaríamos cualquier otro objeto.</p>
<p>En próximos artículos se explicará cómo utilizar las expresiones lambda para generar arboles de procesado.</p>
<p> </p>
<p>Hasta otra!</p>
<br /> Tagged: .NET, C#, Lambda <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/129/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/129/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/129/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/129/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/129/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/129/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/129/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/129/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=129&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2008/11/13/lambda-expressions-expresiones-lambda/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>
	</item>
		<item>
		<title>Single-Page interface (interfaz de página única)</title>
		<link>http://jimenezroda.wordpress.com/2008/11/02/single-page-interface/</link>
		<comments>http://jimenezroda.wordpress.com/2008/11/02/single-page-interface/#comments</comments>
		<pubDate>Sun, 02 Nov 2008 22:52:34 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[ASP.NET AJAX]]></category>
		<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=113</guid>
		<description><![CDATA[La tecnología AJAX nos permite desarrollar aplicaciones web haciendo uso de nuevos diseños (o incluso podríamos decir que paradigmas) complementarios o substitutivos al proceso tradicional de desarrollo de web sites en ASP.NET. Uno de esos métodos de diseño de web sites es el diseño de la interfaz de página única (Single-page interface).  Normalmente, cuando se [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=113&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>La tecnología AJAX nos permite desarrollar aplicaciones web haciendo uso de nuevos diseños (o incluso podríamos decir que paradigmas) complementarios o substitutivos al proceso tradicional de desarrollo de web sites en ASP.NET. Uno de esos métodos de diseño de web sites es el diseño de la interfaz de página única (Single-page interface). </p>
<p><span id="more-113"></span>Normalmente, cuando se acomete la tarea de diseñar una aplicación web, uno intenta reducir el número de páginas a diseñar a la mínima expresión (una página para la autenticación de usuario, otra página con el mapa del site, otra más para la gestión de usuarios, y así hasta obtener un número de páginas que nos permita un mantenimiento relativamente simple de la aplicación, así como para la extensibilidad de la misma). Pues bien, y porqué no crear una aplicación web que sólo disponga de una única página (WebForm)?</p>
<p>Imaginemos la siguiente situación:</p>
<p>Tenemos una página que dispone de un menú horizontal en la parte superior de la pantalla. Este menú nos permite navegar por nuestro site. La imagen muestra el escenario descrito:</p>
<p><a href="http://jimenezroda.files.wordpress.com/2008/10/diseno.jpg"><img class="aligncenter size-medium wp-image-115" title="Distribución de la aplicación web" src="http://jimenezroda.files.wordpress.com/2008/10/diseno.jpg?w=300&#038;h=244" alt="" width="300" height="244" /></a></p>
<p>Sin tener en cuenta el modelo de interfaz de página unica, podríamos decidir crear un webform para el &#8220;Home&#8221;, otra para &#8220;Manager&#8217;s Zone&#8221;, una más para &#8220;Costumers&#8221; y así por cada uno de los items que contiene el menú. Pero el diseño (alternativo, por supuesto) que vamos a proponer sólo dispone de una única página aspx (un único webform). Al hacer click sobre cada uno de los items del menú, lo que haremos es enviar una petición asíncrona para recargar el contenido de el único control que contiene nuestra página, un <em>UpdatePanel</em>. Este UpdatePanel contiene un control <em>PlaceHolder </em>donde iremos substituyendo los controles por aquellos que deban ser mostrados en cada momento. Cabe recordar que para hacer uso de ASP.NET AJAX es necesario incorporar el control ScriptManager a la página, e indicar al control UpdatePanel, cual o cuales serán los disparadores (triggers) que harán que el UpdatePanel se recargue. Para que se vea la propuesta, aquí muestro el diseño en Visual Web Developer:</p>
<p><a href="http://jimenezroda.files.wordpress.com/2008/10/diseno-proyecto.jpg"><img class="aligncenter size-medium wp-image-118" title="Proyecto Visual Web Developer" src="http://jimenezroda.files.wordpress.com/2008/10/diseno-proyecto.jpg?w=300&#038;h=155" alt="" width="300" height="155" /></a></p>
<p>Nosotros crearemos UserControl&#8217;s por cada uno de los items del menú (podríamos añadir los controles necesario para cada item de forma programática, pero hemos decidido utilizar UserControl&#8217;s). Asi pues, cuando el usuario seleccione un item del menú, se cargará el UserControl adecuado. Para ello, añadiremos al UpdatePanel un disparador (trigger) que apunte al evento <strong>MenuItemClick</strong> tal y como muestra esta imagen:<br />
<a href="http://jimenezroda.files.wordpress.com/2008/10/trigger.jpg"><img class="aligncenter size-medium wp-image-119" title="Disparador de recarga" src="http://jimenezroda.files.wordpress.com/2008/10/trigger.jpg?w=300&#038;h=214" alt="" width="300" height="214" /></a><br />
Todos los eventos que se lancen desde el UserControl que se ha cargado en el UpdatePanel, se ejecutarán de forma asíncrona. Esto lleva implícito un problema: Cuando el usuario lanza un evento del UserControl al servidor, evidentemente se ejecuta un Postback en el que se envian <span style="text-decoration:underline;">todos los datos</span> de la página actual. Cuando ASP recibe la petición lo que hace es cargar los controles que se han especificado en el webForm solicitado (es decir, se cargan los controles de la única página que se ha especificado). Esto significa que los controles que se han cargado dinamicamente (es decir el contenido del PlaceHolder del UpdatePanel, en nuestro caso el UserControl) ASP no los cargará.</p>
<p>Intentaré explicarlo de forma más simple. Cuando ASP recibe una petición por una determinada página (por ejemplo la página Defualt.aspx) ocurre lo siguiente:</p>
<p style="padding-left:30px;">- ASP cogerá la página Default.aspx y la utilizará a modo de plantilla, creando en memoria los controles y los tags html que se indican en la misma.</p>
<p style="padding-left:30px;">- Después, utilizará los datos del ViewState que llegan en la petición para rellenar los datos y reestablecer el estado de los controles que se han generado en memória.</p>
<p>Así pues, ASP cargará el control PlaceHolder, pero no su contenido. Será responsabilidad nuestra cargar en el PlaceHolder el control que ha lanzado el evento que ha provocado el Postback que se está tratando. Evidentemente cargaremos el control siempre y cuando el Postback <span style="text-decoration:underline;">no esté provocado por el menú</span>.</p>
<p>Para determinar la procedéncia del PostBack, haremos uso de una propiedad del control ScriptManager (control necesario para hacer uso de ASP.NET AJAX) llamada <em>AsyncPostBackSourceElementID</em>. Esta propiedad nos indicará el Identificador del control que ha lanzado el PostBack. Si el postback proviene del menu, cargaremos en el control UpdatePanel (mejor dicho, en el PlaceHolder que hay en su interior) el UserControl perteneciente al item seleccionado. En caso de que el Postback esté generado por otro control, primero será necesario recargar el UserControl actual con tal de que pueda recargar los datos que le llegan del Postback, y ejecutar los eventos que el usuario haya lanzado. </p>
<p>A continuación muestro el código que proporciona la funcionalidad que hemos comentado:</p>
<p style="padding-left:30px;"> </p>
<p><span style="color:#0000ff;">using</span> System;<br />
<span style="color:#0000ff;">using</span> System.Collections.Generic;<br />
<span style="color:#0000ff;">using</span> System.Linq;<br />
<span style="color:#0000ff;">using</span> System.Web;<br />
<span style="color:#0000ff;">using</span> System.Web.UI;<br />
<span style="color:#0000ff;">using</span> System.Web.UI.WebControls;</p>
<p><span style="color:#0000ff;">public partial class</span> _Default : System.Web.UI.Page <br />
{</p>
<p>    /// &lt;summary&gt;<br />
    /// Constante que identifica el control cargado actualmente en el UpdatePanel<br />
    /// &lt;/summary&gt;</p>
<p>   <span style="color:#0000ff;"> private const string</span> ViewStateControl = <span style="color:#993300;">&#8220;CurrentLoadedControl&#8221;</span>;   </p>
<p>    <span style="color:#0000ff;">protected void</span> Page_Load(<span style="color:#0000ff;">object</span> sender, EventArgs e)<br />
    {</p>
<p>        <span style="color:#99cc00;">//Al hacer un load, debemos saber si es por un postback o por que se ha<br />
        //generado la pagina por primera vez. <br />
        //Si es un postback, es necesario saber si lo ha producido el menu, o alguno<br />
        //de los UserControls que hemos cargado en el UpdatePanel</span></p>
<p>        <span style="color:#0000ff;">if</span> (IsPostBack &amp;&amp; !IsAMenuItemPostBack())<br />
        {</p>
<p>           <span style="color:#99cc00;"> //El postback lo ha producido un usercontrol cargado en el UpdatePanel,<br />
            //por lo tanto, debemos recargar ese control con tal de que le lleguen los <br />
            //datos de Postback (que estan contenidos en el ViewState) y se pueda atender el <br />
            //evento que ha generado el PostBack.<br />
 </span></p>
<p>            Control control = <span style="color:#0000ff;">null</span>;</p>
<p>            <span style="color:#0000ff;">try</span><br />
            {<br />
                control = <span style="color:#0000ff;">this</span>.LoadControl(ViewState[ViewStateControl] <span style="color:#0000ff;">as</span> <span style="color:#0000ff;">string</span>);<br />
            }<br />
            <span style="color:#0000ff;">catch</span> (Exception)<br />
            {<br />
                <span style="color:#0000ff;">throw</span>;<br />
            }</p>
<p>            <span style="color:#0000ff;">if</span> (control != <span style="color:#0000ff;">null</span>)<br />
            {<br />
                MainPlaceHolder.Controls.Add(control);<br />
            }<br />
        }<br />
    }</p>
<p>    <span style="color:#0000ff;">protected void</span> MainMenu_MenuItemClick(<span style="color:#0000ff;">object</span> sender, MenuEventArgs e)<br />
    {<br />
        <span style="color:#99cc00;">//Si el item seleccionado no es el actual, se debe cargar el UserControl<br />
        //que debe mostrarse en el UpdatePanel.</span></p>
<p>        <span style="color:#0000ff;">string</span> controlToLoad = e.Item.Value+&#8221;<span style="color:#993300;">.aspx</span>&#8220;;</p>
<p>        <span style="color:#0000ff;">if</span> (ViewState[ViewStateControl] <span style="color:#0000ff;">as string</span> != controlToLoad)<br />
        {<br />
            Control control = LoadControl(controlToLoad); </p>
<p>            <span style="color:#0000ff;">if</span> (control != null)<br />
            {<br />
                MainPlaceHolder.Controls.Clear();<br />
                MainPlaceHolder.Controls.Add(control); </p>
<p>                ViewState[ViewStateControl] = controlToLoad;<br />
            }<br />
        }<br />
    }</p>
<p>    <span style="color:#0000ff;">private bool</span> IsAMenuItemPostBack()<br />
    {<br />
        <span style="color:#99cc00;">//Miramos si el control que ha generado el Postback es el MainMenu.</span><br />
        <span style="color:#0000ff;">if</span> (MyScriptManager.AsyncPostBackSourceElementID == &#8220;<span style="color:#993300;">MainMenu</span>&#8220;)<br />
            <span style="color:#0000ff;">return true;<br />
        else<br />
            return false</span>;<br />
    }<br />
}</p>
<p>Queda claro en el código que es necesario dar a la propiedad Value de cada MenuItem el nombre del UserControl que se va a cargar (es una propuesta de funcionamiento. Bien podríamos utilizar una clausula switch o if anidados si se cree conveniente. </p>
<p>Así es como implementaríamos la interfaz de página única. De esta forma obtendriamos una aplicación totalmente implementada haciendo uso de AJAX, lo que proporcionará una interfaz de usuario más interactiva.</p>
<p> </p>
<p>Es evidente que sobre este modelo pueden discutirse la mantenibilidad y extensibilidad (quizás más complejas que en otros modelos), pero no es mi intención vender este modelo como la única ni mejor alternativa, pero si como eso, como una alternativa. No todos los proyectos requieren de un modelo en tres capas, ni de una inversión enorme en el diseño del mismo para que sea fácil su mantenimiento. Evidentemente hay que evaluar las ventajas e inconvenientes de este modelo antes de proponerlo siquiera como solución a algún problema aunque esta práctica debería hacerse con cualquier modelo y/o paradigma. Y digo esto último porque pocas veces alguien se atreve a cuestionar que utilizar el paradigma de la programación orientada a objetos sea el conveniente para un proyecto concreto (cuando es una de las primeras cuestiones que deberíamos plantearnos). Hay alternativas a este paradigma que nos pueden facilitar el desarrollo de un proyecto (paradigma de programación guiada por eventos, programación secuencial, programación funcional, programación basada en políticas, y muchos otros paradigmas).</p>
<p>Como siempre, espero que os resulte interesante este artículo. Espero vuestros comentarios!!!</p>
<p>Gracias!! <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<br /> Tagged: ASP.NET, ASP.NET AJAX <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/113/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=113&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2008/11/02/single-page-interface/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/diseno.jpg?w=300" medium="image">
			<media:title type="html">Distribución de la aplicación web</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/diseno-proyecto.jpg?w=300" medium="image">
			<media:title type="html">Proyecto Visual Web Developer</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/trigger.jpg?w=300" medium="image">
			<media:title type="html">Disparador de recarga</media:title>
		</media:content>
	</item>
		<item>
		<title>Partial methods (Métodos parciales)</title>
		<link>http://jimenezroda.wordpress.com/2008/10/16/partial-methods-metodos-parciales/</link>
		<comments>http://jimenezroda.wordpress.com/2008/10/16/partial-methods-metodos-parciales/#comments</comments>
		<pubDate>Thu, 16 Oct 2008 22:04:35 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[Novedades .NET Framework 3.5]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[VB.NET]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=101</guid>
		<description><![CDATA[Los métodos parciales son una nueva caracterísitca de los lenguajes C# 3.0 y VB.NET 9.0. Los métodos parciales nos permitirán declarar y utilizar métodos sin estar éstos implementados.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=101&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Los métodos parciales son una nueva característica de los lenguajes C# 3.0 y VB.NET 9.0. Los métodos parciales nos permitirán declarar y utilizar métodos sin estar éstos implementados.</p>
<p><span id="more-101"></span>Hay que tener presente que para implementar métodos parciales es necesario implementar clases parciales. <br />
Como hemos comentado, los métodos parciales nos permiten hacer referencia a un método que todavía no ha sido implementado. Imaginemos que trabajamos en un equipo de desarrollo. Es responsabilidad nuestra implementar un método tal como este:</p>
<p style="padding-left:30px;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">double</span> <em>RealizarContabilidad</em>(<span style="color:#0000ff;">guid</span> referenciaExpediente)</p>
<p>Los demás desarrolladores necesitan poder hacer la llamada a éste método con tal de dejar acabada sus respectivos módulos. Si implementamos los métodos parciales, los demás desarrolladores pueden acabar sus módulos y continuar con sus desarrollos y nosotros retrasar la implementación lo necesario.  </p>
<p>Entremos en materia. Para declarar un método parcial utilizaremos la siguiente sintaxis:</p>
<p style="padding-left:30px;"> <span style="color:#0000ff;">modificador_acceso partial tipo_retorno</span> <em>nombre_método</em>(parámetros);</p>
<p>Ejemplo:</p>
<p style="padding-left:30px;"><span style="color:#0000ff;">public partial double</span> <em>RealizarContabilidad</em>(<span style="color:#0000ff;">guid</span> referenciaExpediente);</p>
<p>Ahora podríamos hacer lo siguiente:</p>
<pre><code><span><strong>C#</strong></span>
 public partial class PartialClassSample
 {
   <strong>
   //Declaración del método parcial
   partial double RealizarContabilidad(guid referenciaExpediente);</strong>

   public void DoSomething()
   {
     ...
     <strong>RealizarContabilidad(Guid.NewGuid()); //<span>Usamos el método pese a no estar implementado
                   </span></strong>
   }

 }
<strong>
</strong><span><strong>VB.NET</strong></span>
 Partial Public Class PartialClassSample

<strong>   Partial Private Sub RealizarContabilidad(ByVal referenciaExpediente As Guid)
   End Sub</strong>

  Public Function DoSomething() As Double
    ...
    <strong>RealizarContabilidad</strong><strong>(Guid.NewGuid()) <span>' Usamos el método parcial</span></strong>
  End Sub

 End Class</code>
<span style="font-family:0;">
</span></pre>
<p><span>Ahora deberíamos implementar el método tal que así:</span></p>
<p><strong>C#</strong></p>
<pre><code> public partial class PartialClassSample
 {
   partial double RealizarContabilidad(guid referenciaExpediente)
   {
     return 20.0f;
   }
 }

<span><strong>VB.Net</strong></span>
 Partial Public Class PartialClassSample
   Private Fucntion RealizarContabilidad(ByVal referenciaExp As Guid)As Double
     Return 20.0
   End Sub
 End Class</code>

<span style="font-family:'Lucida Grande';line-height:19px;white-space:normal;">Cuando el compilador encuentra una llamada a un método parcial, busca en cada una de las partes de la clase para encontrar la implementación del mismo.
Si la encuentra, la utiliza, Sino, ignora cualquier llamada al método en
concreto. </span>
<span style="font-family:'Lucida Grande';line-height:19px;white-space:normal;">
</span><span style="font-family:'Lucida Grande';line-height:19px;white-space:normal;">Espero que os sea útil. Un saludo! <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </span></pre>
<br /> Tagged: .NET, ASP.NET, C#, VB.NET <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/101/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=101&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2008/10/16/partial-methods-metodos-parciales/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>
	</item>
		<item>
		<title>Creando aplicaciones AJAX seguras (Securing AJAX apps)</title>
		<link>http://jimenezroda.wordpress.com/2008/10/15/creando-aplicaciones-ajax-seguras/</link>
		<comments>http://jimenezroda.wordpress.com/2008/10/15/creando-aplicaciones-ajax-seguras/#comments</comments>
		<pubDate>Wed, 15 Oct 2008 21:14:10 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[ASP.NET AJAX]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=28</guid>
		<description><![CDATA[En esta entrada se intenta explicar cómo crear aplicaciones ASP.NET AJAX más seguras añadiendo una capa intermedia que nos permita implementar un cierto nivel de seguridad.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=28&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Varias semanas atrás leí un artículo acerca de cómo desarrollar aplicaciones web más seguras cuando se hace uso de AJAX y el artículo me dio pie a escribir esta entrada, ya que estoy convencido de que para muchos de nosotros desarrollar aplicaciones más seguras es uno de los objetivos principales.</p>
<p>Cuando desarrollamos aplicaciones web, podríamos afirmar que en la mayoría de casos la arquitectura que se acaba implementado es una arquitectura en dos capas (Cliente &#8211; Servidor) cómo la que se muestra en la imagen:</p>
<p> </p>
<div id="attachment_91" class="wp-caption aligncenter" style="width: 194px"><a href="http://jimenezroda.files.wordpress.com/2008/10/initial-status.jpg"><img class="size-full wp-image-91" title="initial-status" src="http://jimenezroda.files.wordpress.com/2008/10/initial-status.jpg?w=184&#038;h=132" alt="Arquitectura en dos capas" width="184" height="132" /></a><p class="wp-caption-text">Arquitectura en dos capas</p></div>
<p><span id="more-28"></span></p>
<p>Ésta arquitectura lleva implícito un riesgo si utilizamos AJAX en el cliente: el front-end accederá al back-end haciendo uso de los servicios que éste último publica mediante una interfaz o API. El riesgo consiste en que estos servicios son <em>públicos </em>(sino no podríamos acceder a ellos mediante AJAX o Silverlight), es decir, que están abiertos a cualquiera que quiera hacer uso de ellos (sea mediante nuestro cliente o a través de cualquier otro canal). El caso más habitual es el uso de WebServices en la parte back-end. Estos servicios web són incapaces, por si mismos, de diferenciar si la llamada está siendo efectuada por un cliente propio o por un agente externo (y probablemente con intenciones maliciosas) ya que lo único que el cliente hace es llamar una URL con un conjunto de parámetros y recibir la respuesta del servicio. </p>
<p>Cualquier barrera que planteáramos poner en este nivel (firewalls, por ejemplo) privaría de acceder al servicio tanto a propios como ajenos, por lo que nadie podría acceder al mismo.</p>
<p>Si no se hiciera uso de AJAX, esto no sería un problema, puesto que la llamada al servicio se realizaría desde el propio Servidor, y esta ya se encuentra controlada ya que el servidor ya se encarga de comprobar que el usuario que realiza la petición se encuentre autenticado y esté autorizado (ASP.NET Authentication).</p>
<p>En caso de utilizar AJAX, sería necesario implementar esta comprobación por nosotros mismos.</p>
<p>Actualmente se ha aceptado como diseño de arquitectura, colocar una capa llamada <strong><em>Capa de servicios (<span style="font-weight:normal;"><span style="font-style:normal;">o Service layer) que es la capa a la que accede el front-end (AJAX en este caso) y que se encarga de gestionar todos los pasos necesarios para generar la respuesta esperada por el cliente (la capa de servicios se encarga de acceder a los servicios, objetos de negocio o de ejecutar workflows (flujos de trabajo) con tal de obtener una respuesta correcta). Aun así, esta capa no nos proporciona la seguridad esperada si accedemos a ella mediante AJAX o Silverlight (es decir, de forma asíncrona) ya que sigue siendo imposible determinar si la llamada proviene de un cliente autorizado o de un cliente que no lo está.</span></span></em></strong></p>
<p>La solución que se propone es añadir una capa intermedia, entre el front-end y la capa de Servicios, con tal de que esta quede protegida. Esta capa se denomina AJAX Service Layer (o capa de servicios AJAX) y es la capa a la que se conecta el front-end y la encargada de comprobar que éstos dispongan de los permisos adecuados para poder acceder a dicho servicio. Para hacernos una idea, la arquitectura propuesta es la siguiente:</p>
<p> </p>
<div id="attachment_92" class="wp-caption aligncenter" style="width: 391px"><a href="http://jimenezroda.files.wordpress.com/2008/10/service-layer.jpg"><img class="size-full wp-image-92" title="service-layer" src="http://jimenezroda.files.wordpress.com/2008/10/service-layer.jpg?w=381&#038;h=213" alt="Capa de servicios" width="381" height="213" /></a><p class="wp-caption-text">Capa de servicios</p></div>
<p> </p>
<p> </p>
<div id="attachment_93" class="wp-caption aligncenter" style="width: 393px"><a href="http://jimenezroda.files.wordpress.com/2008/10/ajax-service-layer.jpg"><img class="size-full wp-image-93" title="ajax-service-layer" src="http://jimenezroda.files.wordpress.com/2008/10/ajax-service-layer.jpg?w=383&#038;h=293" alt="Arquitectura con AJAX Service Layer" width="383" height="293" /></a><p class="wp-caption-text">Arquitectura con AJAX Service Layer</p></div>
<p> </p>
<p> </p>
<p> </p>
<p>Pero vayamos paso a paso:</p>
<p style="padding-left:30px;">Con tal de implementar seguridad en aplicaciones que utilicen Silverlight o AJAX, se propone utilizar, tal y como se ha comentado, una capa intermedia, llamada Capa de Servicios AJAX (AJAX Service Layer). Las aplicaciones cliente (entiéndase AJAX o Silverlight) deberán realizar cualquier petición a la capa de servicios AJAX (ya que la situaremos entre el front-end y la capa de servicios (Service Layer). </p>
<p style="padding-left:30px;">La responsabilidad de la capa de servicios AJAX es comprobar si la llamada que esta recibiendo proviene de un cliente autorizado o no. Si la comprobación resulta afirmativa, lo que se hará es llamar al correspondiente servicio de la capa de servicios (Service Layer) con tal de devolver la respuesta esperada. En caso negativo, se lanzará un error.</p>
<p style="padding-left:30px;">¿Y cómo determinará la capa de servicios AJAX si la llamada proviene de un cliente autorizado? Pues muy simple: comprobaremos que el usuario esté autenticado. ¿Cómo? una llamada AJAX hace un <em>Postback del estado actual de la aplicación</em>. Entre los datos que recibimos estará la <strong>Cookie de Autenticación</strong>. Podremos, así pues, comprobar que el usuario esté autenticado. </p>
<p style="padding-left:30px;">Obviamente, para ello deberemos hacer pasar al usuario por un proceso de autenticación y autorización previamente a la utilización de aquellos servicios que requieran la autenticación del usuario por motivos de seguridad. No está de más recordar como se configura la autenticación y autorización de usuarios. En el archivo <em>web.config</em> podremos especificar la autorización de un grupo de usuarios creando una entrada como la siguiente:</p>
<p style="padding-left:30px;"> </p>
<pre class="libCScode">&lt;location path="MembersOnly"&gt;
    &lt;system.web&gt;
        &lt;authorization&gt;
            &lt;deny users="?" /&gt;
        &lt;/authorization&gt;
    &lt;/system.web&gt;
&lt;/location&gt;</pre>
<p>Para especificar el modo de autenticación (Forms, Windows Integrated, Passport,etc..) se puede crear una entrada tal que esta:</p>
<pre class="libCScode">&lt;authentication mode="Forms"&gt;
    &lt;forms loginUrl="MembersOnly/login.aspx"&gt;
    &lt;/forms&gt;
&lt;/authentication&gt;</pre>
<p style="padding-left:30px;">Y eso es todo. Si tenéis cualquier duda o propuesta de mejora para esta solución, no dudéis en dejarla patente en forma de comentario. La discusión y el debate nos harán a todos mejores programadores. <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="padding-left:30px;">Hasta pronto!:)</p>
<br /> Tagged: .NET, ASP.NET AJAX, Security <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/28/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=28&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2008/10/15/creando-aplicaciones-ajax-seguras/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/initial-status.jpg" medium="image">
			<media:title type="html">initial-status</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/service-layer.jpg" medium="image">
			<media:title type="html">service-layer</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/ajax-service-layer.jpg" medium="image">
			<media:title type="html">ajax-service-layer</media:title>
		</media:content>
	</item>
		<item>
		<title>Friendly Assemblies (Ensamblados Amigos)</title>
		<link>http://jimenezroda.wordpress.com/2008/10/14/friendly-assemblies-ensamblados-amigos/</link>
		<comments>http://jimenezroda.wordpress.com/2008/10/14/friendly-assemblies-ensamblados-amigos/#comments</comments>
		<pubDate>Tue, 14 Oct 2008 22:28:40 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[.NET Framework 3.0]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Friendly Assemblies]]></category>
		<category><![CDATA[VB.NET]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=78</guid>
		<description><![CDATA[Los ensamblados amigos nos permiten compartir los miembros declarados como Friend o Internal con otros ensamblados determinados.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=78&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>En este artículo se pretende describir que son los friendly assemblies (o ensamblados amigos) y como implementarlos. Este es un concepto que ya existía en la versión VB.NET 2005 (8.0) y en C# 2.0.</p>
<p>El concepto de ensamblado amigo nos indica que un ensamblado <em>podrá compartir sus miembros <strong>Friend / Internal </strong>con otros ensamblados</em> determinados (es decir, que tenemos que especificar explícitamente).<span id="more-78"></span><br />
Esto podremos conseguirlo haciendo uso del Atributo:</p>
<p style="padding-left:30px;"><em>&lt;InternalsVisibleTo( &#8230; )&gt;    o    [InternalsVisibleTo( ...)] </em></p>
<p>En principio, cuando declaramos los miembros de un assembly (ya sean clases, o los miembros de las propias clases) como Friend o Internal, estos sólo son accesibles desde el propio assembly (cabe recordar que si no se especifica el modificador de acceso, <em>VB.NET establece como modificador de acceso por defecto <strong>Friend</strong>, mientras que C# establece <strong>Internal</strong></em>, lo que conceptualmente es exactamente lo mismo). Si decidimos que éstos miembros deben ser visibles sólo para ciertos assemblies, entonces podemos decantarnos por dos opciones:</p>
<p style="padding-left:30px;">- Declaramos los miembros a compartir como Protected Friend o Internal Protected (lo cual nos obliga a que todos los miembros del assembly (sea cual sea) que contengan objetos que derivan de los miembros a compartir puedan acceder a dichos miembros.</p>
<p style="padding-left:30px;">- Usamos los ensamblados amigos.</p>
<p>Si nos decantamos por la segunda opción, podremos especificar los assemblies con acceso a los miembros Friend o Internal del assembly actual utilizando el atributo &lt;InternalsVisibleTo()&gt; en el archivo AssemblyInfo del siguiente modo:</p>
<pre>&lt;Assembly: InternalsVisibleTo(<span>"Ensamblado_amigo, PublicKey=llave pública"</span>)&gt; 

[assembly: <span>InternalsVisibleTo</span>(<span>"Ensamblado_amigo, PublicKey=llave pública"</span>)]</pre>
<p>Para poder usar este atributo, es necesario hacer referencia al espacio de nombres <span><em><strong>S</strong></em></span><em><strong>ystem.Runtime.CompilerServices;</strong></em></p>
<p>Una vez hecho esto, ya podremos utilizar los miembros Friend o Internal en los ensamblados especificados. Se pueden especificar ensamblados amigos en VB.NET 8.0 o superior y en C# 2.0 o superior, pero sólo pueden consumirse en C#2.0 o superior y en VB.NET 9.0.</p>
<p>Y eso es todo. Otra cuestión muy diferente es si el uso de ensamblados amigos rompe con algunas de las bases de la POO, pero eso es otro cantar! Hasta Pronto! <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br /> Tagged: .NET, C#, Friendly Assemblies, VB.NET <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/78/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=78&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2008/10/14/friendly-assemblies-ensamblados-amigos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>
	</item>
		<item>
		<title>Relaxed delegates (Relajación de delegados)</title>
		<link>http://jimenezroda.wordpress.com/2008/10/14/relaxed-delegates-relajacion-de-delegados/</link>
		<comments>http://jimenezroda.wordpress.com/2008/10/14/relaxed-delegates-relajacion-de-delegados/#comments</comments>
		<pubDate>Tue, 14 Oct 2008 21:48:39 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[Novedades .NET Framework 3.5]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Relaxed Delegates]]></category>
		<category><![CDATA[VB.NET]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=67</guid>
		<description><![CDATA[La relajación de delegados nos permite pasar, como parámetros de un delegado, objetos de la misma jerarquia de clases (contravarianza) que el objeto que indica la firma del método.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=67&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>La relajación de delegados es otra de las nuevas características del lenguaje VB.NET (9.0) (que ya venía incluida en la versión 2.0 del lenguaje C#). </p>
<p>Un poco de historia para contextualizar esta característica:</p>
<p>Como todos sabemos, un delegado no es sino un <em><strong>puntero</strong><span style="font-style:normal;"> que hace referencia a una dirección de memoria que contiene la firma de un método (y el método en sí). En versiones anteriores (podríamos ir directamente al lenguaje C++ para comprobar esto)</span></em> la firma del método era fuerte (strong).<span id="more-67"></span> Eso quiere decir que el método espero un <em>numero determinado de parámetros</em> y espera que <em>cada uno de éstos parámetros sea de un tipo específico </em>y, finalmente, <em>devolverá un objeto de un tipo concreto</em><em><span style="font-style:normal;"> (o no devolverá nada)</span>. <span style="font-style:normal;">Ejemplo</span>:</em></p>
<p style="padding-left:60px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Sub</span> DoSomething(<span style="color:#0000ff;">ByVal</span> Param1 <span style="color:#0000ff;">As String</span>, <span style="color:#0000ff;">ByVal</span> Param2 <span style="color:#0000ff;">As StringDictionary</span>)</p>
<p>Los <strong>delegados</strong> nacieron como una via para <em>envolver</em> la firma de un método, de forma que <em>se podía comprobar, antes de llamar a un método, que a éste se le pasaban los parámetros adecuados</em> (tanto en número como en tipos). </p>
<p>Imaginemos la siguiente situación:</p>
<p>Como es bien sabido, todos los tipos de objetos del .NET Framework derivan de la clase <em><span style="color:#0000ff;">Object</span></em> . Imaginemos, pues, que, haciendo uso de la OO, decidimos realizar la siguiente operación:</p>
<p style="padding-left:60px;"> </p>
<p style="padding-left:60px;"><span style="color:#0000ff;">Imports</span> System.Runtime.CompilerServices<br />
<span style="color:#0000ff;">Imports</span> System.Collections.Specialized</p>
<p style="padding-left:60px;"><span style="color:#0000ff;">Public Class</span> TryRelaxedDelegates</p>
<p style="padding-left:60px;">    <span style="color:#0000ff;">Private Delegate Sub</span> DoSomething(<span style="color:#0000ff;">ByVal</span> Param1 <span style="color:#0000ff;">As String</span>, <span style="color:#0000ff;">ByVal</span> Param2 <span style="color:#0000ff;">As StringDictionary</span>)</p>
<p style="padding-left:60px;">    <span style="color:#0000ff;">Public Sub</span> ProbarDelegado()<br />
        <span style="color:#0000ff;">Dim</span> delegado <span style="color:#0000ff;">As New</span> DoSomething(<span style="color:#0000ff;">AddressOf</span> HacerAlgo)<br />
        delegado(<span style="color:#0000ff;"><strong><em>New Object</em></strong></span>, <strong><em><span style="color:#0000ff;">New Object</span></em></strong>)<br />
    <span style="color:#0000ff;">End Sub</span></p>
<p style="padding-left:60px;"><span style="color:#0000ff;">    Private Sub</span> HacerAlgo(<span style="color:#0000ff;">ByVal</span> str <span style="color:#0000ff;">As String</span>, <span style="color:#0000ff;">ByVal</span> strdic <span style="color:#0000ff;">As StringDictionary</span>)</p>
<p style="padding-left:60px;">      <span style="color:#0000ff;">  Console</span>.WriteLine(&#8220;OK!&#8221;)</p>
<p style="padding-left:60px;">    <span style="color:#0000ff;">End Sub</span></p>
<p style="padding-left:60px;"><span style="color:#0000ff;">End Class</span></p>
<p> </p>
<p>¿qué ocurrirá? Pues la verdad es que la respuesta, a dia de hoy, será: Depende</p>
<p>- Si utilizamos una versión de C# (entendiendo que el código anterior debería traducirse a C#) anterior a la versión 2.0 o utilizamos VB.NET 8.0 o anterior, esta operación nos dará un error de compilación, puesto que los parámetros que le hemos pasado a la función no se corresponden con la firma del delegado y, por lo tanto, se producirá un error de compilación.</p>
<p>- Sin embargo, si utilizamos C# 2.0 o posterior o bien Vb.NET 9.0, esta operación (la mostrada en el código, dónde estamos pasando Object&#8217;s en vez de objetos con el tipo esperado) está permitida. Esto es gracias a la<em><strong> relajación de delegados</strong><span style="font-style:normal;"> . Ahora se habilita la posibilidad de utilizar, no solo lo objetos que indica la firma del método, sino también todos aquellos que estén dentro de la misma herencia de clases (</span>contravarianza<span style="font-style:normal;">). Así pues, imaginemos que tenemos la siguiente estructura de clases:</span></em></p>
<p><a href="http://jimenezroda.files.wordpress.com/2008/10/hierachysample1.jpg"><img class="aligncenter size-full wp-image-71" title="hierachysample1" src="http://jimenezroda.files.wordpress.com/2008/10/hierachysample1.jpg?w=123&#038;h=228" alt="" width="123" height="228" /></a></p>
<p>Gracias a la relajación de delegados, podríamos declarar un delegado que apuntara al siguiente método:</p>
<p style="padding-left:30px;"><span style="color:#0000ff;">Public Function</span> ObtenerNombreDoctor(<span style="color:#0000ff;">ByVal</span> Doctor <span style="color:#0000ff;">As</span> Doctor) <span style="color:#0000ff;">As String</span></p>
<p>y llamarlo de las siguientes formas:</p>
<p style="padding-left:30px;"><span style="color:#0000ff;">Dim</span> doc <span style="color:#0000ff;">As New</span> Doctor (<span style="color:#993300;">&#8220;Román&#8221;</span>)<br />
<span style="color:#0000ff;">Dim</span> per <span style="color:#0000ff;">As New</span> Persona (<span style="color:#800000;">&#8220;Alberto&#8221;</span>)<br />
<span style="color:#0000ff;">Dim</span> obj <span style="color:#0000ff;">As Object</span> </p>
<p style="padding-left:30px;"> - ObtenerNombreDoctor(doc) &#8211;&gt; Funciona, ya que cumple con la firma del método<br />
 - ObtenerNombreDoctor(per) &#8211;&gt; Funciona, gracias a la relajación de delegados y a la contravarianza<br />
 - ObtenerNombreDoctor(obj) &#8211;&gt; Lo mismo que en el caso anterior<br />
 - ObtenerNombreDoctor() &#8211;&gt; También funciona (en VB.NET) ya que la relajación llega al extremo de no tener que indicar ningún parámetro. </p>
<p>Pues bien, eso es todo en cuanto a la relajación de delegados (Relaxed delegates). Como siempre, espero volver a veros por aquí! <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<br /> Tagged: .NET, C#, Relaxed Delegates, VB.NET <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/67/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=67&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2008/10/14/relaxed-delegates-relajacion-de-delegados/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/hierachysample1.jpg" medium="image">
			<media:title type="html">hierachysample1</media:title>
		</media:content>
	</item>
		<item>
		<title>Anonymous types (Tipos anónimos)</title>
		<link>http://jimenezroda.wordpress.com/2008/10/12/anonymous-types-tipos-anonimos/</link>
		<comments>http://jimenezroda.wordpress.com/2008/10/12/anonymous-types-tipos-anonimos/#comments</comments>
		<pubDate>Sun, 12 Oct 2008 21:19:17 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[Novedades .NET Framework 3.5]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[VB.NET]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=41</guid>
		<description><![CDATA[Los tipos anónimos nos permiten crear tipos de datos sin declararlos de forma explícita. Podemos encontrar su máxima utilidad en LINQ, donde las consultas pueden simplificarse mucho con la ayuda de los tipos anónimos.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=41&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Anonymous types (o tipos anónimos, también llamados <em>projections</em>) es una nueva característica que incorporan las nuevas versiones de los lenguajes C# y VB.NET (3.0 y 9.0 respectivamente). <br />
Los tipos anónimos nos permiten declarar tipos al momento, sin tener que hacer una declaración explícita (es decir, sin tener que crear una clase).  Los tipos anónimos tienen una mayor utilidad en las expresiones LINQ, ya que estas sentencias muchas veces no se mapean a una entidad lógica concreta y requieren la creación de un nuevo tipo de objetos al momento (on the fly) para poder ser tratadas posteriormente.<span id="more-41"></span></p>
<p>Nada mejor que un poco de código para comprender mejor lo explicado.</p>
<p><strong>VB.NET:</strong></p>
<p style="padding-left:30px;"><strong></strong>Existen diferencias sintácticas entre los dos lenguajes que tratamos en este blog asiduamente (VB.NET y C#) con respecto a los tipos anónimos.<br />
Para declarar un tipo anónimo en VB.NET se hace uso de la palabra reservada <strong><span style="color:#0000ff;">With</span></strong>, tal y como se muestra en la siguiente imagen:</p>
<p> </p>
<div id="attachment_46" class="wp-caption aligncenter" style="width: 510px"><a href="http://jimenezroda.files.wordpress.com/2008/10/anonymoustypesvbnet1.jpg"><img class="size-full wp-image-46" title="anonymoustypesvbnet1" src="http://jimenezroda.files.wordpress.com/2008/10/anonymoustypesvbnet1.jpg?w=500&#038;h=131" alt="Declaración de un tipo anónimo en VB.NET. Observar como el compilador detecta las propiedades declaradas." width="500" height="131" /></a><p class="wp-caption-text">Figura 1: Declaración de un tipo anónimo en VB.NET. Observar como el compilador detecta las propiedades declaradas.</p></div>
<p> </p>
<p style="padding-left:30px;">Tal y como puede observarse en la imagen, el compilador ya detecta las propiedades que tiene el nuevo tipo de objetos y que hemos especificado en la declaración (inline) de la propia variable. <br />
Cabe destacar el uso <em>necesario</em> de la palabra reservada <strong><span style="color:#0000ff;">With</span></strong> para especificar que se está declarando un tipo anónimo, así como el uso del punto para especificar el inicio de la declaración de un atributo del tipo en i.  </p>
<p> </p>
<p><strong>C#:</strong></p>
<p style="padding-left:30px;">A continuación se muestra el mismo ejemplo pero utilizando C# como lenguaje de programación. A destacar las diferencias en la sintaxis. No es necesario hacer uso de la palabra reservada <strong><span style="color:#0000ff;">With</span></strong> y tampoco es necesario comenzar los nombres de los atributos con un  punto:</p>
<p style="padding-left:30px;"> </p>
<div id="attachment_62" class="wp-caption aligncenter" style="width: 310px"><a href="http://jimenezroda.files.wordpress.com/2008/10/anonymoustypesc1.jpg"><img class="size-medium wp-image-62" title="anonymoustypesc1" src="http://jimenezroda.files.wordpress.com/2008/10/anonymoustypesc1.jpg?w=300&#038;h=142" alt="Aqui también puede apreciarse como el compilador detecta las propiedades del objeto que se ha declarado inline en la linea anterior" width="300" height="142" /></a><p class="wp-caption-text">Figura 2: Aquí también puede apreciarse como el compilador detecta las propiedades del objeto que se ha declarado inline en la línea anterior</p></div>
<p> </p>
<p> </p>
<p>Nótese como se hace uso de la palabra reservada <strong><span style="color:#0000ff;">var</span></strong>, ya que en éste ejemplo también hay implícito el uso de la <a class="aligncenter" title="Type Inference" href="http://jimenezroda.wordpress.com/2008/10/12/type-inference-inferencia-de-tipos/" target="_self">inferéncia de tipos.</a></p>
<p>En el caso de VB.NET, será necesario tener activada la opción <em><strong>Option Infer On</strong></em> con tal de que este ejemplo compile correctamente.</p>
<p><em>Pero, ¿cómo actúa el compilador para conseguir éste resultado? ¿Cada vez que declaro un tipo anónimo se crea un nuevo tipo interno?</em><br />
Son buenas preguntas con respuestas simples:<br />
- Cuando declaramos un tipo anónimo, el compilador actúa creando un tipo interno exactamente igual que si nosotros lo hubiéramos creado de forma explícita, es decir, creando una clase (directamente en código MSIL) con un nombre del tipo <strong><em>&lt;proyección&gt;f__0.</em></strong></p>
<p>- Los tipos anónimos están tipados, por lo que, si nosotros declaramos otra variable del tipo anónimo utilizando la misma sintaxis que en los ejemplos, el compilador <em>no</em> crearía otro tipo de datos, sino que instanciaría un nuevo objeto haciendo uso del tipo antes declarado. En cambio, si cambiamos el orden en el que definimos los atributos (por ejemplo, primero indicamos los <em>Apellidos</em> y luego el <em>Nombre</em>, el compilador lo interpretará como un nuevo tipo de datos y creará, de forma interna, otro tipo de datos distinto.</p>
<p>Para finalizar, sólo cabe mencionar que los tipos anónimos son de contexto local, por lo que si pasamos como parámetro un tipo anónimo a otro assembly, éste no podrá determinar el tipo a menos que hagamos uso de la <em>Reflexión</em> (Reflection).</p>
<p>Y eso es todo por el momento. Espero que esta información os resulte interesante y os sea útil. Hasta pronto!</p>
<br /> Tagged: .NET, C#, VB.NET <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/41/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=41&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2008/10/12/anonymous-types-tipos-anonimos/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/anonymoustypesvbnet1.jpg" medium="image">
			<media:title type="html">anonymoustypesvbnet1</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/anonymoustypesc1.jpg?w=300" medium="image">
			<media:title type="html">anonymoustypesc1</media:title>
		</media:content>
	</item>
		<item>
		<title>Type inference (Inferencia de tipos)</title>
		<link>http://jimenezroda.wordpress.com/2008/10/12/type-inference-inferencia-de-tipos/</link>
		<comments>http://jimenezroda.wordpress.com/2008/10/12/type-inference-inferencia-de-tipos/#comments</comments>
		<pubDate>Sun, 12 Oct 2008 21:18:59 +0000</pubDate>
		<dc:creator>Javier Jiménez Roda</dc:creator>
				<category><![CDATA[Novedades .NET Framework 3.5]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Inferéncia de tipos]]></category>
		<category><![CDATA[Type Inference]]></category>

		<guid isPermaLink="false">http://jimenezroda.wordpress.com/?p=11</guid>
		<description><![CDATA[La inferéncia de tipos es una nueva característica del .NET Framework 3.5. Esta nos permite definir variables sin especificar el tipo de la misma hasta que no se instáncia por primera vez.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=11&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>El lanzamiento del .NET Framework 3.5 trae consigo una nueva versión del CLR asi como una nueva versión de VB.NET (9.0 o 2008) y C# (3.0) (éstos son los lenguajes que trato en éste blog).</p>
<p>Una de las nuevas características que incorporan éstos lenguajes es la inferencia de tipos. Para entender este nuevo concepto, creo que es mejor empezar con un ejemplo práctico:</p>
<p><strong>VB.NET:</strong></p>
<p style="padding-left:30px;">Partamos del siguiente código</p>
<p style="padding-left:60px;"><span style="color:#3366ff;">Dim</span> i=<span style="color:#3366ff;">new</span> <em>ArrayList</em>()     &#8211;&gt; Notar que se ha omitido la especificación del tipo (<span style="color:#0000ff;">As</span> XXXX)</p>
<p style="padding-left:30px;">Uno espera que el comportamiento del compilador sea tratar la variable <em>i</em> como un<br />
ArrayList, pero si comprobamos con IntelliSense la variable veremos que el<br />
compilador la trata como un <em>Object.<span id="more-11"></span></em> La inferencia de datos soluciona este problema. <br />
Si activamos la opción  <em>Option Strict On, </em>el compilador no dará un error en la sentencia anterior, puesto que no hemos indicado el tipo de la variable declarada, i los tipos no son convertibles de forma implícita.</p>
<p style="padding-left:30px;">Es muy recomendable programar con la opción <em>Option Strict </em>activada puesto que nos impedirá generar este tipo de código.</p>
<p style="padding-left:30px;">Si activamos la opción <em>Option Infer On</em> podremos introducir el siguiente código:</p>
<p style="padding-left:60px;">Option Infer On<br />
Dim i = new ArrayList()</p>
<p style="padding-left:30px;">El compilador, ahora es capaz de inferir el tipo del objeto i, reconociendo a éste como un objeto del tipo ArrayList. </p>
<p style="padding-left:30px;">Más ejemplos de Inferencia de tipos:</p>
<p style="padding-left:30px;"> </p>
<div id="attachment_20" class="wp-caption aligncenter" style="width: 494px"><a href="http://jimenezroda.files.wordpress.com/2008/10/inferencia-de-tipos-vb-no-infer-no-strict.jpg"><img class="size-full wp-image-20" title="inferencia-de-tipos-vb-no-infer-no-strict" src="http://jimenezroda.files.wordpress.com/2008/10/inferencia-de-tipos-vb-no-infer-no-strict.jpg?w=484&#038;h=205" alt="Option Strict y Option Infer = Off" width="484" height="205" /></a><p class="wp-caption-text">Option Strict y Option Infer = Off (El compilador trata la variable i como Object, no como ArrayList)</p></div>
<p style="padding-left:30px;"> </p>
<p> </p>
<div id="attachment_19" class="wp-caption aligncenter" style="width: 510px"><a href="http://jimenezroda.files.wordpress.com/2008/10/inferencia-de-tipos-vb-no-infer-con-strict.jpg"><img class="size-full wp-image-19" title="inferencia-de-tipos-vb-no-infer-con-strict" src="http://jimenezroda.files.wordpress.com/2008/10/inferencia-de-tipos-vb-no-infer-con-strict.jpg?w=500&#038;h=230" alt="Option Strict On (no nos permite este tipo de declaraciones, ya que los tipos no se pueden convertir de forma implicita)" width="500" height="230" /></a><p class="wp-caption-text">Option Strict On (no nos permite este tipo de declaraciones, ya que los tipos no se pueden convertir de forma implícita)</p></div>
<p style="padding-left:30px;"> </p>
<p style="padding-left:30px;"> </p>
<div id="attachment_18" class="wp-caption aligncenter" style="width: 484px"><a href="http://jimenezroda.files.wordpress.com/2008/10/inferencia-de-tipos-vb-con-infer-y-strict-activados.jpg"><img class="size-full wp-image-18" title="inferencia-de-tipos-vb-con-infer-y-strict-activados" src="http://jimenezroda.files.wordpress.com/2008/10/inferencia-de-tipos-vb-con-infer-y-strict-activados.jpg?w=474&#038;h=248" alt="Con Option Strict y Option Infer On, la inferencia de tipos funciona correctamente" width="474" height="248" /></a><p class="wp-caption-text">Con Option Strict y Option Infer On, la inferencia de tipos funciona correctamente</p></div>
<p>Para activar las opciones Option Strict y/o Option Infer (o bien deshabilitarlas) para todo nuestro proyecto, podemos hacerlo accediendo a las propiedades del proyecto y modificándolo en la pestaña de Compilación:</p>
<p> </p>
<div id="attachment_21" class="wp-caption aligncenter" style="width: 509px"><a href="http://jimenezroda.files.wordpress.com/2008/10/activar-option-strict-para-el-proyecto1.jpg"><img class="size-full wp-image-21" title="activar-option-strict-para-el-proyecto1" src="http://jimenezroda.files.wordpress.com/2008/10/activar-option-strict-para-el-proyecto1.jpg?w=499&#038;h=357" alt="Activando las Options en las propiedades del proyecto, evitaremos tener que declararlas en cada uno de nuestros archivos fuente" width="499" height="357" /></a><p class="wp-caption-text">Activando las Options en las propiedades del proyecto, evitaremos tener que declararlas en cada uno de nuestros archivos fuente</p></div>
<p> </p>
<p><strong>C#:</strong></p>
<p style="padding-left:30px;">La inferencia de tipos en C# se puede implementar haciendo uso de la palabra reservada <em>var</em>. La sintaxis para declarar una variable haciendo uso de la inferencia de tipos seria así:</p>
<p style="padding-left:60px;"><span style="color:#0000ff;">var</span> i=<span style="color:#0000ff;">new</span> ArrayList();</p>
<p style="padding-left:30px;">Ahora la variable i es del tipo ArrayList, pese a que en ningún momento hemos declarado su tipo, tal y como se demuestra en la siguiente imagen:</p>
<p> </p>
<p><a href="http://jimenezroda.files.wordpress.com/2008/10/inference-types-c.jpg"><img class="aligncenter size-full wp-image-17" title="inference-types-c" src="http://jimenezroda.files.wordpress.com/2008/10/inference-types-c.jpg?w=500&#038;h=468" alt="" width="500" height="468" /></a></p>
<p> </p>
<p>Y eso es todo en cuanto a la inferencia de tipos. Espero que os sea útil en vuestro trabajo diario! <img src='http://s2.wp.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<br /> Tagged: .NET, Inferéncia de tipos, Type Inference <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jimenezroda.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jimenezroda.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jimenezroda.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jimenezroda.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jimenezroda.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jimenezroda.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jimenezroda.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jimenezroda.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jimenezroda.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jimenezroda.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jimenezroda.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jimenezroda.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jimenezroda.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jimenezroda.wordpress.com/11/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jimenezroda.wordpress.com&amp;blog=5114581&amp;post=11&amp;subd=jimenezroda&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jimenezroda.wordpress.com/2008/10/12/type-inference-inferencia-de-tipos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7acf02948a29a0be44d91d2afd82874a?s=96&#38;d=monsterid&#38;r=G" medium="image">
			<media:title type="html">jimenezroda</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/inferencia-de-tipos-vb-no-infer-no-strict.jpg" medium="image">
			<media:title type="html">inferencia-de-tipos-vb-no-infer-no-strict</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/inferencia-de-tipos-vb-no-infer-con-strict.jpg" medium="image">
			<media:title type="html">inferencia-de-tipos-vb-no-infer-con-strict</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/inferencia-de-tipos-vb-con-infer-y-strict-activados.jpg" medium="image">
			<media:title type="html">inferencia-de-tipos-vb-con-infer-y-strict-activados</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/activar-option-strict-para-el-proyecto1.jpg" medium="image">
			<media:title type="html">activar-option-strict-para-el-proyecto1</media:title>
		</media:content>

		<media:content url="http://jimenezroda.files.wordpress.com/2008/10/inference-types-c.jpg" medium="image">
			<media:title type="html">inference-types-c</media:title>
		</media:content>
	</item>
	</channel>
</rss>
