<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2spanishfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Climens Codelog</title>
	
	<link>http://codelog.climens.net</link>
	<description>Desarrollo, productividad, blogging, tecnología, vida en la trinchera...</description>
	<lastBuildDate>Fri, 25 Jun 2010 10:00:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ClimensCodelog" /><feedburner:info uri="climenscodelog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>39.473488</geo:lat><geo:long>-0.38939</geo:long><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FClimensCodelog" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FClimensCodelog" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FClimensCodelog" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FClimensCodelog" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://add.my.yahoo.com/content?lg=es&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2FClimensCodelog" src="http://eur.i1.yimg.com/eur.yimg.com/i/es/my/addto1.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.feedness.com/alta/http://feeds.feedburner.com/ClimensCodelog" src="http://www.feedness.com/ayuda/wp-content/square_b_sh_feed.gif">Subscribe with Feedness</feedburner:feedFlare><item>
		<title>Cambio de hosting</title>
		<link>http://feedproxy.google.com/~r/ClimensCodelog/~3/fiY0t7VF29E/</link>
		<comments>http://codelog.climens.net/2010/06/25/cambio-de-hosting/#comments</comments>
		<pubDate>Fri, 25 Jun 2010 10:00:53 +0000</pubDate>
		<dc:creator>climens</dc:creator>
				<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://codelog.climens.net/?p=265</guid>
		<description><![CDATA[Durante este fin de semana tengo previsto cambiar de hosting (de Dreamhost a Silicontower) y de versión de WordPress, así que es posible que ocurran cosas extrañas durante un par de días. Que la fuerza me acompañe.]]></description>
			<content:encoded><![CDATA[<div>
<p>Durante este fin de semana tengo previsto cambiar de hosting (de <a href="http://www.dreamhost.com/">Dreamhost</a> a <a href="http://www.silicontower.net/">Silicontower</a>) y de versión de <a href="http://wordpress.org/">WordPress</a>, así que es posible que ocurran cosas extrañas durante un par de días.</p>
<p>Que la fuerza me acompañe.</p>
</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=fiY0t7VF29E:6uQH3wIGjqc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=fiY0t7VF29E:6uQH3wIGjqc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=fiY0t7VF29E:6uQH3wIGjqc:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=fiY0t7VF29E:6uQH3wIGjqc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=fiY0t7VF29E:6uQH3wIGjqc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=fiY0t7VF29E:6uQH3wIGjqc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=fiY0t7VF29E:6uQH3wIGjqc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=fiY0t7VF29E:6uQH3wIGjqc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=fiY0t7VF29E:6uQH3wIGjqc:t4U8cFwb1qM"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=t4U8cFwb1qM" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ClimensCodelog/~4/fiY0t7VF29E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codelog.climens.net/2010/06/25/cambio-de-hosting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codelog.climens.net/2010/06/25/cambio-de-hosting/</feedburner:origLink></item>
		<item>
		<title>Get MAC from IP address in .NET</title>
		<link>http://feedproxy.google.com/~r/ClimensCodelog/~3/SQlfqGtihzQ/</link>
		<comments>http://codelog.climens.net/2010/06/14/get-mac-from-ip-address-in-net/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 07:38:36 +0000</pubDate>
		<dc:creator>climens</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[networking]]></category>

		<guid isPermaLink="false">http://codelog.climens.net/?p=259</guid>
		<description><![CDATA[After dealing with several options, most of them involving a call to a command line tool and parsing the output, which is not really elegant. Other solutions were based on obsolete VBScript client code and ActiveX, even worse. Finally I found in the excellent pinvoke.net site a very nice and simple example using a simple [...]]]></description>
			<content:encoded><![CDATA[<p>After dealing with several options, most of them involving a call to a command line tool and parsing the output, which is not really elegant. Other solutions were based on obsolete VBScript client code and ActiveX, even worse.</p>
<p>Finally I found in the excellent <a href="http://www.pinvoke.net/">pinvoke.net</a> site <a href="http://www.pinvoke.net/default.aspx/iphlpapi.SendARP">a very nice and simple example</a> using a simple call to iphlpapi.dll&#8217;s SendARP method. The trick was to use <a href="http://en.wikipedia.org/wiki/Address_Resolution_Protocol">ARP</a> to get the MAC from the IP.</p>
<p>Note that this has it&#8217;s limitations, as I will only work if the remote machine is in the same network and the packet does not need to go through a router. I was enough for our needs.</p>
<p>Here&#8217;s the code I adapted from the example:</p>
<p>[csharp]<br />
public static string GetMAC(IPAddress ipAddr)<br />
{<br />
var mac = new byte[6];<br />
var len = (uint)mac.Length;</p>
<p>var result = SendARP((int)ipAddr.Address, 0, mac, ref len);</p>
<p>if (result != 0)<br />
{<br />
return &#8220;MAC not found!&#8221;;<br />
}</p>
<p>var str = new string[(int)len];</p>
<p>for (var i = 0; i &lt; len; i++)<br />
{<br />
str[i] = mac[i].ToString(&#8220;x2&#8243;);<br />
}</p>
<p>return string.Join(&#8220;:&#8221;, str);<br />
}</p>
<p>[DllImport("iphlpapi.dll", ExactSpelling = true)]<br />
private static extern int SendARP(int destIP, int srcIP, byte[] pMacAddr, ref uint phyAddrLen);<br />
[/csharp]</p>
<p>Enjoy!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=SQlfqGtihzQ:Hc70RUhgwzY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=SQlfqGtihzQ:Hc70RUhgwzY:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=SQlfqGtihzQ:Hc70RUhgwzY:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=SQlfqGtihzQ:Hc70RUhgwzY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=SQlfqGtihzQ:Hc70RUhgwzY:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=SQlfqGtihzQ:Hc70RUhgwzY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=SQlfqGtihzQ:Hc70RUhgwzY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=SQlfqGtihzQ:Hc70RUhgwzY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=SQlfqGtihzQ:Hc70RUhgwzY:t4U8cFwb1qM"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=t4U8cFwb1qM" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ClimensCodelog/~4/SQlfqGtihzQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codelog.climens.net/2010/06/14/get-mac-from-ip-address-in-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codelog.climens.net/2010/06/14/get-mac-from-ip-address-in-net/</feedburner:origLink></item>
		<item>
		<title>NHibernate: Custom type is not serializable</title>
		<link>http://feedproxy.google.com/~r/ClimensCodelog/~3/SDaNe8cAOCs/</link>
		<comments>http://codelog.climens.net/2010/06/10/nhibernate-custom-type-is-not-serializable/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 16:02:33 +0000</pubDate>
		<dc:creator>climens</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://codelog.climens.net/?p=253</guid>
		<description><![CDATA[Since I acquired a NHibernateProfiler license, an initialization warning message draw my attention, the text seemed quite easy to solve: WARN: custom type is not Serializable: MyLibrary.MyCustomDataType My first solution was adding [Serializable] attribute to the custom type, but that didn&#8217;t make the trick. As it was only a warning, I did not investigate further at [...]]]></description>
			<content:encoded><![CDATA[<p>Since I acquired a NHibernateProfiler license, an initialization warning message draw my attention, the text seemed quite easy to solve:</p>
<blockquote><p>WARN: custom type is not Serializable: MyLibrary.MyCustomDataType</p></blockquote>
<div>My first solution was adding <code>[Serializable]</code> attribute to the custom type, but that didn&#8217;t make the trick. As it was only a warning, I did not investigate further at that moment.</div>
<div>But the other day, debugging data access code I saw the warning again and the easiest solution was going to the source NHibernate code to find this:</div>
<div>[csharp]TypeFactory.InjectParameters(userType, parameters);<br />
if (!userType.ReturnedClass.IsSerializable)<br />
{<br />
LogManager.GetLogger(typeof(CustomType)).Warn(&#8220;custom type is not Serializable: &#8221; + userTypeClass);<br />
}[/csharp]</p>
</div>
<div>As seen in this code, the message is unclear, because the class that must be serializable is the ReturnedClass, not the custom UserType itself.</div>
<div>So, to solve the warning I just needed to add <code>[Serializable]</code> to the class returned by my custom UserType instead than the type itself.</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=SDaNe8cAOCs:MxVLJsGB8QA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=SDaNe8cAOCs:MxVLJsGB8QA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=SDaNe8cAOCs:MxVLJsGB8QA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=SDaNe8cAOCs:MxVLJsGB8QA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=SDaNe8cAOCs:MxVLJsGB8QA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=SDaNe8cAOCs:MxVLJsGB8QA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=SDaNe8cAOCs:MxVLJsGB8QA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=SDaNe8cAOCs:MxVLJsGB8QA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=SDaNe8cAOCs:MxVLJsGB8QA:t4U8cFwb1qM"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=t4U8cFwb1qM" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ClimensCodelog/~4/SDaNe8cAOCs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codelog.climens.net/2010/06/10/nhibernate-custom-type-is-not-serializable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codelog.climens.net/2010/06/10/nhibernate-custom-type-is-not-serializable/</feedburner:origLink></item>
		<item>
		<title>NHibernate y localización</title>
		<link>http://feedproxy.google.com/~r/ClimensCodelog/~3/OILru6u6wQA/</link>
		<comments>http://codelog.climens.net/2010/03/16/nhibernate-y-localizacion/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 09:45:07 +0000</pubDate>
		<dc:creator>climens</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[localización]]></category>
		<category><![CDATA[lucene]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://codelog.climens.net/?p=246</guid>
		<description><![CDATA[Edit: Cross-posted in NHForge: Localization techniques Hace unos días estuve dándole vueltas en el grupo de NHUsers de nuevo al tema de la localización de propiedades usando NHibernate para ver si se me ocurría una forma más potente de hacerlas, dado que el mecanismo que usamos actualmente no permite usar ordenación a través de SQL, [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Edit</strong>: Cross-posted in NHForge: <a href="http://nhforge.org/wikis/howtonh/localization-techniques.aspx">Localization techniques</a></p>
<p>Hace unos días <a href="http://groups.google.com/group/nhusers/browse_thread/thread/b099f9f4a10a08f6">estuve dándole vueltas en el grupo de NHUsers</a> de nuevo al tema de la localización de propiedades usando NHibernate para ver si se me ocurría una forma más potente de hacerlas, dado que el mecanismo que usamos actualmente no permite usar ordenación a través de SQL, por lo que para ordenar los datos por la columna localizable, hay que procesar todas las entidades, lo que es un problema cuando hay muchas.</p>
<p>En resumen, hay 2 modos fundamentales y ampliamente documentados de hacer campos localizables con NHibernate.</p>
<p><strong>Método 1: Serializando la propiedad a través de un IUserType</strong></p>
<p>Esta aproximación es por ejemplo la que <a href="http://fabiomaulo.blogspot.com/2009/06/localized-property-with-nhibernate.html">describe Fabio Maulo en su blog</a>, usando <a href="http://code.google.com/p/unhaddins/source/browse/trunk/uNhAddIns/uNhAddIns/UserTypes/LocalizablePropertyType.cs">LocalizablePropertyType</a> del proyecto <a href="http://code.google.com/p/unhaddins/">uNHaddins</a>. Básicamente se trata de almacenar todas las cadenas de traducción en un solo campo y el IUserType se encarga de obtener un diccionario u otra estructura más compleja a partir del valor del campo y de almacenar esa misma estructura en forma de string.</p>
<p>En mi caso, no usé exactamente este tipo porque quería almacenar también un identificador de idioma por defecto y algunas cosas más, pero no es algo complicado de hacer.</p>
<p>Internamente normalmente almacenaremos algún tipo de diccionario con el idioma como clave y el valor la traducción pero es sencillo exponer la propiedad como un string haciendo que el get obtenga el valor correcto para el idioma actual (si es que esta funcionalidad no la implementamos en nuestro propio diccionario).</p>
<p>Ventajas:</p>
<ul>
<li>Sencillo de realizar</li>
<li>No se necesitan tablas adicionales</li>
<li>Transparente</li>
</ul>
<p>Inconvenientes:</p>
<ul>
<li>Al ser un campo calculado, no permite usar ORDER BY</li>
<li><span style="text-decoration: line-through">La propiedad no puede ser un string</span></li>
</ul>
<p><strong>Método 2: Almacenar la propiedad en otras tablas</strong></p>
<p>Hay varios ejemplos de cómo realizar esto, básicamente se trata de mapear la propiedad a una estructura de tipo diccionario donde se almacenan las distintas traducciones del valor de la propiedad indexadas por código de la localización (bien en texto o usando el LCID). Esto se puede hacer más o menos complejo, pero fundamentalmente el principio es el mismo.</p>
<p>Todo esto se suele apoyar en una clase que se encarga de almacenar el diccionario de localizaciones y provee métodos para añadir, eliminar y obtener de forma sencilla dichas cadenas, haciendo uso del Thread.CurrentThread.CurrentCulture para obtener el idioma seleccionado actualmente.</p>
<p>Como no, <a href="http://ayende.com/Blog">Ayende</a> ofrece una solución al problema basada en la simplicidad en <a href="http://ayende.com/Blog/archive/2006/12/26/localizingnhibernatecontextualparameters.aspx">Localizing NHibernate: Contextual Parameters</a>, usando una fórmula en el mapping para obtener la propiedad Name de la entidad y un filtro en la sesión para que funcione la fórmula. Igual no soluciona los problemas en todos los escenarios, pero es una lectura interesante.</p>
<p>En esta otra propuesta de <a href="http://www.webdevbros.net">WebDevBros</a>, Michal nos propone <a href="http://www.webdevbros.net/2009/06/24/create-a-multi-languaged-domain-model-with-nhibernate-and-c/">Create a multi languaged domain model with NHibernate and C#</a>. Muy interesante. Por un lado, se crean dos tablas, una con los diferentes diccionarios que corresponderán a las distintas propiedades a localizar, y otra tabla con los valores de cada diccionario, que se mapea con un &lt;map&gt; de forma sencilla. También una clase que sirve para contener las traducciones y facilitar el acceso a las mismas.</p>
<p>En esta misma linea, Siim Viikman muestra en <a href="http://www.siimviikman.com/2010/02/24/mapping-translations-in-nhibernate/">Mapping translations in NHibernate</a> una aproximación muy similar a la anterior que conviene también leer porque aporta otra variante a la solución. Esta quizás no es tan cómoda de usar como la anterior pero puede tener sus ventajas.</p>
<p>En <a href="http://www.codewrecks.com/blog/index.php?p=41">Localizable entities with Nhibernate</a> (<a href="http://www.codewrecks.com/blog/index.php?p=41">Part1</a>, <a href="http://www.codewrecks.com/blog/index.php?p=42">Part2</a> y <a href="http://www.codewrecks.com/blog/index.php/2007/05/23/localize-entity-with-nhibernate-part-3/">Part3</a>), Alkampfer propone una solución algo compleja, que se basa en un objeto que mantiene el idioma actual seleccionado durante el ciclo de vida de la aplicación y en una clase de apoyo que gestiona las traducciones. Es de lectura muy interesante aunque en mi opinión se puede hacer lo mismo evitando el objeto Registry que crea y usando <em>Thread.CurrentThread.CurrentCulture</em>.</p>
<p>Ventajas:</p>
<ul>
<li>Uso de todas las posibilidades de la base de datos y SQL</li>
</ul>
<p>Inconvenientes:</p>
<ul>
<li>Mapeo más complejo (dificil en algunos casos o imposible usando Fluent NHibernate)</li>
<li>Más tablas, más datos</li>
</ul>
<p><strong>Conclusión</strong></p>
<p>En resumen, las propiedades traducibles o localizables son un problema difícil de resolver que generan una capa de complejidad en el acceso a datos y en la gestión de dichas traducciones. Aun así me puedo aventurar a dar ciertos consejos</p>
<ul>
<li>Antes de localizar una propiedad, pensar si realmente es necesario ¿realmente es necesario?</li>
<li>Si no vamos a necesitar ordenación u indexación por SQL, el método basado en IUserType es más que suficiente y ahorramos problemas. NOTA: Si se quiere indexación, siempre se puede usar <a href="http://lucene.apache.org/lucene.net/">Lucene.NET</a> y <a href="http://darioquintana.com.ar/blogging/2007/12/09/nhibernate-search/">NHibernate.Search</a> con un Bridge personalizado que almacene todos los idiomas.</li>
<li>Si necesitamos ordenación, seguramente será solo en algunos campos concretos, así que podemos solamente usar el segundo método en los campos más críticos para simplificar nuestra vida.</li>
</ul>
<p>En mi caso al final hemos optado por una solución mixta, usando el primer método en la mayoría de los casos y cuando se ha necesitado tener listados grandes ordenados por la propiedad localizable, hemos optado por una solución parecida a la de WebDevBros pero con una tabla por cada campo localizable porque no son muchos y el mapeo es más simple.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=OILru6u6wQA:i1zVz24XUdg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=OILru6u6wQA:i1zVz24XUdg:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=OILru6u6wQA:i1zVz24XUdg:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=OILru6u6wQA:i1zVz24XUdg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=OILru6u6wQA:i1zVz24XUdg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=OILru6u6wQA:i1zVz24XUdg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=OILru6u6wQA:i1zVz24XUdg:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=OILru6u6wQA:i1zVz24XUdg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=OILru6u6wQA:i1zVz24XUdg:t4U8cFwb1qM"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=t4U8cFwb1qM" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ClimensCodelog/~4/OILru6u6wQA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codelog.climens.net/2010/03/16/nhibernate-y-localizacion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codelog.climens.net/2010/03/16/nhibernate-y-localizacion/</feedburner:origLink></item>
		<item>
		<title>Lo mejor de 2009</title>
		<link>http://feedproxy.google.com/~r/ClimensCodelog/~3/NCiWEaPh16w/</link>
		<comments>http://codelog.climens.net/2009/12/31/lo-mejor-de-2009/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 13:03:05 +0000</pubDate>
		<dc:creator>climens</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[bestof]]></category>
		<category><![CDATA[top10]]></category>

		<guid isPermaLink="false">http://codelog.climens.net/?p=243</guid>
		<description><![CDATA[Como cada año, este post hace un repaso de lo más leído de 2009. La verdad que ha sido un año de altibajos, con pocas entradas pero en mi opinión de mejor calidad y más específicos y útiles (para el que le sirvan) que los publicados anteriormente. Además he introducido algunos posts más en inglés [...]]]></description>
			<content:encoded><![CDATA[<p>Como cada año, este post hace un repaso de lo más leído de 2009. La verdad que ha sido un año de altibajos, con pocas entradas pero en mi opinión de mejor calidad y más específicos y útiles (para el que le sirvan) que los publicados anteriormente. Además he introducido algunos posts más en inglés con temas que creo que no estaban explicados en ningún sitio.</p>
<p>El más leido de 2009, <a href="http://codelog.climens.net/2009/01/29/nhibernate-burrow-and-nhibernate-search/">NHibernate Burrow and NHibernate Search</a>, explicando la integración de estas dos estupendas librerías. <a href="http://nhforge.org/wikis/burrow/home.aspx">Burrow</a> permite manejar sencillamente las sesiones de NHibernate en entornos web y Search permite integrar con Lucene. También escribí <a href="http://codelog.climens.net/2009/01/27/nhibernate-burrow-y-nhibernate-search/">la versión en español</a> del artículo.</p>
<p>Más de NHibernate: <a href="http://codelog.climens.net/2009/03/04/nhibernate-validator-custom-messages/">NHibernate Validator custom messages</a>, o cómo conseguí personalizar los mensajes del validator mediante extensibilidad de un modo muy sencillo y potente. Supongo que con el tiempo <a href="http://nhforge.org/wikis/validator10/nhibernate-validator-1-0-0-documentation.aspx">Validator </a>soportará esto nativamente.</p>
<p>Después otro más en inglés, <a href="http://codelog.climens.net/2009/08/05/asp-net-mvc-and-returnurl/">ASP.NET MVC and ReturnUrl</a>, quejándome de que muchos ejemplos de autenticación con MVC no respetan el parámetro ReturnUrl correctamente, lo que es un error a la hora de hacer un mecanismo útil de autenticación.</p>
<p>Y por último, los <a href="http://codelog.climens.net/2009/06/02/principios-basicos-de-oop-solid/">Principios básicos de OOP: SOLID</a> que siempre deberíamos tener todos presentes a la hora de diseñar una aplicación y mantener la coherencia, la facilidad de uso y la mantenibilidad.</p>
<p>Y dado que este año no he escrito mucho, lo voy a dejar aquí. En 2010, más ASP.NET MVC, más NHibernate y más de todo.</p>
<p>¡Feliz 2010!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=NCiWEaPh16w:2QoVTYhv5kE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=NCiWEaPh16w:2QoVTYhv5kE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=NCiWEaPh16w:2QoVTYhv5kE:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=NCiWEaPh16w:2QoVTYhv5kE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=NCiWEaPh16w:2QoVTYhv5kE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=NCiWEaPh16w:2QoVTYhv5kE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=NCiWEaPh16w:2QoVTYhv5kE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=NCiWEaPh16w:2QoVTYhv5kE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=NCiWEaPh16w:2QoVTYhv5kE:t4U8cFwb1qM"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=t4U8cFwb1qM" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ClimensCodelog/~4/NCiWEaPh16w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codelog.climens.net/2009/12/31/lo-mejor-de-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codelog.climens.net/2009/12/31/lo-mejor-de-2009/</feedburner:origLink></item>
		<item>
		<title>Mis feeds sobre NHibernate y ASP.NET MVC</title>
		<link>http://feedproxy.google.com/~r/ClimensCodelog/~3/1KtMotYDT44/</link>
		<comments>http://codelog.climens.net/2009/11/18/mis-feeds-sobre-nhibernate-y-asp-net-mvc/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 14:23:13 +0000</pubDate>
		<dc:creator>climens</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://codelog.climens.net/?p=240</guid>
		<description><![CDATA[Hace tiempo que tengo un par de feeds en Google Reader que me gustaría compartir con todo el mundo que le puedan interesar. El primero es sobre NHibernate y el segundo sobre ASP.NET MVC, dos temas que sigo de cerca porque los uso diariamente en mi trabajo, recogiendo noticias que van apareciendo en los blogs [...]]]></description>
			<content:encoded><![CDATA[<p>Hace tiempo que tengo un <strong>par de feeds en Google Reader que me gustaría compartir</strong> con todo el mundo que le puedan interesar.</p>
<p>El primero es <strong>sobre NHibernate</strong> y el segundo <strong>sobre ASP.NET MVC</strong>, dos temas que sigo de cerca porque los uso diariamente en mi trabajo, recogiendo noticias que van apareciendo en los blogs a los que estoy suscrito. Por supuesto hay muchas en inglés porque la mayoría de la información se publica en este idioma aunque intento poner cosas en español también:</p>
<ul>
<li><a href="http://feeds.feedburner.com/climens_nhibernate">NHibernate Feed</a></li>
<li><a href="http://feeds.feedburner.com/climens_aspnetmvc">ASP.NET MVC Feed</a></li>
</ul>
<p>Espero que resulten de utilidad.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=1KtMotYDT44:-xpzITG5of4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=1KtMotYDT44:-xpzITG5of4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=1KtMotYDT44:-xpzITG5of4:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=1KtMotYDT44:-xpzITG5of4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=1KtMotYDT44:-xpzITG5of4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=1KtMotYDT44:-xpzITG5of4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=1KtMotYDT44:-xpzITG5of4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=1KtMotYDT44:-xpzITG5of4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=1KtMotYDT44:-xpzITG5of4:t4U8cFwb1qM"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=t4U8cFwb1qM" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ClimensCodelog/~4/1KtMotYDT44" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codelog.climens.net/2009/11/18/mis-feeds-sobre-nhibernate-y-asp-net-mvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codelog.climens.net/2009/11/18/mis-feeds-sobre-nhibernate-y-asp-net-mvc/</feedburner:origLink></item>
		<item>
		<title>Getting MIME type in .NET from file extension</title>
		<link>http://feedproxy.google.com/~r/ClimensCodelog/~3/vbaCc4zXPB0/</link>
		<comments>http://codelog.climens.net/2009/10/28/getting-mime-type-in-net-from-file-extension/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 13:00:49 +0000</pubDate>
		<dc:creator>climens</dc:creator>
				<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://codelog.climens.net/?p=234</guid>
		<description><![CDATA[After some research, I posted a question at stackoverflow.com without much success, but the problem was that the answer was already there. I you are working on any application that needs to serve files on it&#8217;s own, for example for encrypted storage or a rich ACL that needs to be enforced, you will need to [...]]]></description>
			<content:encoded><![CDATA[<p>After some research, I <a href="http://stackoverflow.com/questions/1612767/file-extensions-and-mime-types-in-net">posted a question</a> at <a href="http://stackoverflow.com/">stackoverflow.com</a> without much success, but the problem was that the answer was already there.<br />
I you are working on any application that needs to serve files on it&#8217;s own, for example for encrypted storage or a rich ACL that needs to be enforced, you will need to provide <strong>the most correct Content-Type possible or MIME type from a given file extension</strong> to the reponse in order to achieve the best user experience.<br />
For example, if you serve a PDF and use a generic MIME like application/octet-stream, the user may not se a PDF reader to open it, depending on the browser and platform.<br />
Then, in .NET there are 4 alternatives to do this, with their pros and their cons:</p>
<ol>
<li><strong>Use <a href="http://stackoverflow.com/questions/1029740/get-a-mime-from-an-extention/1029796#1029796">the Windows registry</a></strong> &#8211; This may be a good solution for desktop applications but depends on the software installed on the machine and typically web servers don&#8217;t have Acrobat or Office.</li>
<li><strong>Use <a href="http://stackoverflow.com/questions/58510/in-c-how-can-you-find-the-mime-type-of-a-file-based-on-the-file-signature-not-th/58570#58570">urlmon.dll&#8217;s FindMimeFromData</a></strong> &#8211; I don&#8217;t know exactly the efectiveness of this method, but it&#8217;s used internally by Windows. It should give good and reliable information but you have to read the file and give the method up to 256 bytes of the file header.</li>
<li>Use <a href="http://stackoverflow.com/questions/174888/asp-net-iis6-how-to-search-the-servers-mime-map/174988#174988">IIS information</a> &#8211; Maybe the most obscure mechanism, based on Directory Services and COM stuff. It&#8217;s based on the same mechanism IIS uses, so it should be quite reliable, but complex and may not be the fastest.</li>
<li>Use your own dictionary &#8211; Maybe not the most elegant but even .NET uses this internally (see System.Web.MimeMapping&#8230; <a href="http://www.red-gate.com/products/reflector/">you know how</a>). You get a bunch of types <a href="http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types">from somewhere</a> and add them to a dictionary with the associated extension. Easy.</li>
</ol>
<p>So, the optiones are clear. Finally in my case, I used a simple dictionary to ensure compatibility between platforms and homogeneity. Using other mechanisms could lead to strange errors on some platforms that I wanted to avoid over other benefits. But there are <a href="http://stackoverflow.com/questions/1612767/file-extensions-and-mime-types-in-net/1623612#1623612">much more elaborate mechanisms</a> that can be done.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=vbaCc4zXPB0:clBXF-KFs5E:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=vbaCc4zXPB0:clBXF-KFs5E:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=vbaCc4zXPB0:clBXF-KFs5E:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=vbaCc4zXPB0:clBXF-KFs5E:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=vbaCc4zXPB0:clBXF-KFs5E:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=vbaCc4zXPB0:clBXF-KFs5E:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=vbaCc4zXPB0:clBXF-KFs5E:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=vbaCc4zXPB0:clBXF-KFs5E:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=vbaCc4zXPB0:clBXF-KFs5E:t4U8cFwb1qM"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=t4U8cFwb1qM" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ClimensCodelog/~4/vbaCc4zXPB0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codelog.climens.net/2009/10/28/getting-mime-type-in-net-from-file-extension/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codelog.climens.net/2009/10/28/getting-mime-type-in-net-from-file-extension/</feedburner:origLink></item>
		<item>
		<title>ASP.NET MVC and ReturnUrl</title>
		<link>http://feedproxy.google.com/~r/ClimensCodelog/~3/KKbztd3dD-I/</link>
		<comments>http://codelog.climens.net/2009/08/05/asp-net-mvc-and-returnurl/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 07:11:27 +0000</pubDate>
		<dc:creator>climens</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>

		<guid isPermaLink="false">http://codelog.climens.net/?p=227</guid>
		<description><![CDATA[I&#8217;ve seen many ASP.NET MVC samples and some of them do not honor de ReturnUrl parameter, rendering this unusable. Classic ASP.NET has the login form component that puts the same exact URL used to access the login page in the form action URL, preserving the ReturnUrl parameter and then, FormsAuthentication.GetReturnUrl() gets it from the Request.QueryString [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve seen many ASP.NET MVC samples and some of them do not honor de <code>ReturnUrl</code> parameter, rendering this unusable.</p>
<p>Classic ASP.NET has the login form component that puts the same exact URL used to access the login page in the form action URL, preserving the <code>ReturnUrl</code> parameter and then, <code>FormsAuthentication.GetReturnUrl()</code> gets it from the <code>Request.QueryString</code> collection.</p>
<p>Fortunately, the <code>GetReturnUrl()</code> method looks as well in <code>Request.Form</code> in case there&#8217;s nothing in the query, this way, we can use a hidden field as well to store the <code>ReturnUrl</code> in the View and pass it through POST when the login form is submitted.</p>
<p>So, in ASP.NET MVC we have two options:</p>
<ol>
<li>Use simply <code>Html.BeginForm()</code> without parameters, which will put a simple form tag, with the same URL as the current one and use POST by default</li>
<li>If we want to have more control on the <code>Html.BeginForm()</code>, put a <em>hidden field</em> with the value of the <code>ReturnUrl</code>, <strong>only if the ReturnUrl is not empty</strong>, or it will fail. This can be obtained from the <code>Request.QueryString</code> collection, the ViewData if we put it previously on the Controller action or even better store it in the ViewModel and have a strong typed reference.</li>
</ol>
<p>And that&#8217;s it. Then, <code>FormsAuthentication.GetReturnUrl()</code> will get the proper URL and other methods like <code>FormsAuthentication.RedirectFromLoginPage()</code> will also work seamlessly.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=KKbztd3dD-I:fgmSXkfrNYw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=KKbztd3dD-I:fgmSXkfrNYw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=KKbztd3dD-I:fgmSXkfrNYw:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=KKbztd3dD-I:fgmSXkfrNYw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=KKbztd3dD-I:fgmSXkfrNYw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=KKbztd3dD-I:fgmSXkfrNYw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=KKbztd3dD-I:fgmSXkfrNYw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=KKbztd3dD-I:fgmSXkfrNYw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=KKbztd3dD-I:fgmSXkfrNYw:t4U8cFwb1qM"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=t4U8cFwb1qM" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ClimensCodelog/~4/KKbztd3dD-I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codelog.climens.net/2009/08/05/asp-net-mvc-and-returnurl/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://codelog.climens.net/2009/08/05/asp-net-mvc-and-returnurl/</feedburner:origLink></item>
		<item>
		<title>El principio KISS</title>
		<link>http://feedproxy.google.com/~r/ClimensCodelog/~3/Rbj3btthf7M/</link>
		<comments>http://codelog.climens.net/2009/07/28/el-principio-kiss/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 06:00:28 +0000</pubDate>
		<dc:creator>climens</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[consejos]]></category>
		<category><![CDATA[testeo]]></category>

		<guid isPermaLink="false">http://codelog.climens.net/?p=210</guid>
		<description><![CDATA[El nombre del principio es el acrónimo del inglés Keep It Simple, Stupid o Keep It Short and Simple. El sentido, se puede imaginar. Es en realidad la aplicación de lo que se conoce como La Navaja de Occam (Ockham&#8217;s Razor) aplicado a la informática. Todo se basa en una simple premisa: &#8220;dadas dos soluciones [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/claycarson/3652656445/"><img class="alignright" src="http://farm4.static.flickr.com/3635/3652656445_81628b2f59.jpg" alt="" width="320" height="480" /></a>El nombre del principio es el acrónimo del inglés <em>Keep It Simple, Stupid</em> o <em>Keep It Short and Simple</em>. El sentido, se puede imaginar. Es en realidad la aplicación de lo que se conoce como <a href="http://es.wikipedia.org/wiki/Navaja_de_Occam">La Navaja de Occam</a> (<em>Ockham&#8217;s Razor</em>) aplicado a la informática. Todo se basa en una simple premisa: &#8220;dadas dos soluciones a un problema determinado, la más simple es probablemente la correcta&#8221;.</p>
<p>Aplicado al mundo del desarrollo de software, lo que se conoce como el principio <a href="http://es.wikipedia.org/wiki/Principio_KISS">KISS</a>, implica resolver los problemas del modo más sencillo posible y posiblemente ésta sea la mejor solución.</p>
<p><strong>Código</strong><br />
Desde el punto de vista del código tiene más implicaciones a parte de la simplicidad:</p>
<ul>
<li>Un código más simple es más sencillo de mantener, lo que ahorrará tiempo en el futuro.</li>
<li>Además, será más sencillo de comprender por cualquier persona que entre en el equipo de desarrollo.</li>
<li>Cuesta menos de escribir</li>
<li>Menos lineas equivalen a menos bugs, lo que significa código de mayor calidad</li>
</ul>
<p><strong>Gestión de proyectos</strong><br />
Pero todo esto carece de sentido si desde no se tiene también en cuenta desde el nivel de gestión de los proyectos de software. Es estupendo pensar en miles de funcionalidades para un producto pero ¿qué sentido tienen? Primero habrá que hacer lo más simple para luego ir añadiendo más cosas a una base sencilla y comprensible.</p>
<p>Hay que construir software sobre una base sólida y unos requisitos simples y concretos. Esto permitirá desarrollar unas funcionalidades simples y robustas en menos tiempo y una vez el producto tiene cara y ojos, se pueden ver las carencias y se pueden encontrar nuevas posibilidades.</p>
<p>Pensar en cientos de funcionalidades, además tiene otras implicaciones menos obvias:</p>
<ul>
<li>Tests de usuario menos frecuentes pero mucho más complejos y largos.</li>
<li>Bugs más difíciles de encontrar y de solucionar.</li>
<li>Time-To-Login (tiempo entre que se empieza el desarrollo hasta que se tiene una primera release) mucho más alto.</li>
</ul>
<p>Muchas de las metodologías ágiles se basan en parte en este principio para desarrollar un software evolutivo en vez de crear gran cantidad de especificaciones y documentos que pueden tardar años en implementarse y meses en integrarse.</p>
<p>En resumen, antes de escribir un método, piensa si no lo estás complicando demasiado y antes de añadir un requisito a una release&#8230; piensa si realmente es necesaria en ese momento. Recuerda: KISS.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=Rbj3btthf7M:99VRHLanGfM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=Rbj3btthf7M:99VRHLanGfM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=Rbj3btthf7M:99VRHLanGfM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=Rbj3btthf7M:99VRHLanGfM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=Rbj3btthf7M:99VRHLanGfM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=Rbj3btthf7M:99VRHLanGfM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=Rbj3btthf7M:99VRHLanGfM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=Rbj3btthf7M:99VRHLanGfM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=Rbj3btthf7M:99VRHLanGfM:t4U8cFwb1qM"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=t4U8cFwb1qM" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ClimensCodelog/~4/Rbj3btthf7M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codelog.climens.net/2009/07/28/el-principio-kiss/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codelog.climens.net/2009/07/28/el-principio-kiss/</feedburner:origLink></item>
		<item>
		<title>Principios básicos de OOP: SOLID</title>
		<link>http://feedproxy.google.com/~r/ClimensCodelog/~3/DvYGQ5hFqBk/</link>
		<comments>http://codelog.climens.net/2009/06/02/principios-basicos-de-oop-solid/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 14:55:47 +0000</pubDate>
		<dc:creator>climens</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[consejos]]></category>
		<category><![CDATA[oop]]></category>

		<guid isPermaLink="false">http://codelog.climens.net/?p=204</guid>
		<description><![CDATA[Últimamente reviso mucho código, tanto mío como de otros y me doy cuenta de que muchas veces se pasan por alto los principios básicos del paradigma de orientación a objetos y en muchos casos porque la formación es deficiente o inexistente. Así pues, uno de los acrónimos en el mundillo de la programación orientada a [...]]]></description>
			<content:encoded><![CDATA[<p>Últimamente reviso mucho código, tanto mío como de otros y me doy cuenta de que muchas veces se pasan por alto los principios básicos del paradigma de orientación a objetos y en muchos casos porque la formación es deficiente o inexistente.<br />
Así pues, uno de los acrónimos en el mundillo de la programación orientada a objetos (OOP) es SOLID, que sirve de regla mnemotécnica para recordar 5 principios básicos:</p>
<p><strong>SRP: Single Responsibility Principle:</strong><br />
El principio de responsabilidad única nos dice que <em>nunca debe haber más de un motivo para que una clase cambie</em>, o lo que es lo mismo, que una clase solamente debe tener un propósito. Esto parece simple pero en realidad es uno de los principios más fáciles de violar y muchas veces no es fácil distinguir las responsabilidades.</p>
<p><strong>OCP: Open-Closed Principle:</strong><br />
El principio abierto/cerrado implica que las clases de software deben estar abiertas para la extensión pero cerradas para la modificación. Este es el principio por el cual se hacen privadas las variables del miembro o que no se usan variables globales. El truco de este principio está en la abstracción. Las clases abstractas implementan un código inalterable desde fuera pero obligan a extender de ellas para usar este código a parte de que se promueve la reusabilidad.</p>
<p><strong>LSP: Liskov Substitution Principle:</strong><br />
El principio de sustitución de Liskov implica que las clases derivadas deberían poder ser sustituidas por sus clases base. Es decir, es en cierto modo una extensión del principio anterior: mientras que OCP promueve la herencia de clases base, LSP promueve que la herencia se haga de forma transparente, es decir, que heredar es bueno pero no hay que olvidar las raíces. Es decir, no implementemos un método en una clase heredada que no esté en la clase base porque romperemos este principio.</p>
<p>De OCP y LSP se deduce que las clases base (abstractas o no) modelan el aspecto general y las clases heredadas modelan el comportamiento local.</p>
<p><strong>DIP: Dependency Inversion Principle:</strong><br />
Básicamente, el principio de inversión de dependencia promueve que hay que depender de abstracciones, no de concreciones. Dicho de forma más compleja, los módulos de más alto nivel no deben depender de los de más bajo nivel sino que ambos deben depender de abstracciones. Y a su vez, las abstracciones no deben depender de los detalles sino al contrario.</p>
<p>En este caso, el uso de interfaces resulta muy beneficioso y un framework de inversión de control (<a href="http://www.castleproject.org/container/index.html">Castle Windsor</a>, <a href="http://structuremap.sourceforge.net/">StructureMap</a>, por citar algunos) van a hacer que resulte más obvia la necesidad de abstracciones. Además, el testado unitario resulta mucho más sencillo ya que la independencia entre los distintos módulos es muy elevada.</p>
<p><strong>ISP: Interface Segregation Principle:</strong><br />
Este principio de segregación de interfaces indica que no se debe hacer depender las clases de interfaces que no necesitan y que debe haber granularidad en las interfaces para dotar de aspectos específicos a las distintas implementaciones.</p>
<p>En general, en Java y C# se pueden implementar tantos interfaces como se quiera por lo que es sencillo llevar a cabo este principio. Las interfaces son la forma más práctica de modelar las clases y dotarlas de aspectos particulares así como incluso tratarlas de diferente modo según las interfaces implementadas.</p>
<p>Y estos son básicamente los principios SOLID que aunque llevan ya muchos años siguen siendo vigentes y ayudan a desarrollar un código más reusable, mantenible y claro. Además, con las herramientas actuales de refactorización es muy fácil extraer interfaces y clases abstractas de las ya existentes sin tener que revisar cientos de líneas de código. Y cómo no, tener un buen conjunto de tests unitarios ayudará a que cualquier refactorización se haga sin miedo a romper toda la funcionalidad existente.</p>
<p>Referencias: <a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">Principles of OOD</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=DvYGQ5hFqBk:zbMgpRKh26A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=DvYGQ5hFqBk:zbMgpRKh26A:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=DvYGQ5hFqBk:zbMgpRKh26A:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=DvYGQ5hFqBk:zbMgpRKh26A:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=DvYGQ5hFqBk:zbMgpRKh26A:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=DvYGQ5hFqBk:zbMgpRKh26A:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?i=DvYGQ5hFqBk:zbMgpRKh26A:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=DvYGQ5hFqBk:zbMgpRKh26A:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ClimensCodelog?a=DvYGQ5hFqBk:zbMgpRKh26A:t4U8cFwb1qM"><img src="http://feeds.feedburner.com/~ff/ClimensCodelog?d=t4U8cFwb1qM" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ClimensCodelog/~4/DvYGQ5hFqBk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codelog.climens.net/2009/06/02/principios-basicos-de-oop-solid/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://codelog.climens.net/2009/06/02/principios-basicos-de-oop-solid/</feedburner:origLink></item>
	</channel>
</rss>
