<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Angel "Java" Lopez : C Sharp</title><link>http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx</link><description>Tags: C Sharp</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Code Kata: Capturando páginas web</title><link>http://msmvps.com/blogs/lopez/archive/2009/10/26/code-kata-capturando-p-225-ginas-web.aspx</link><pubDate>Mon, 26 Oct 2009 09:31:03 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1735292</guid><dc:creator>lopez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1735292</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/10/26/code-kata-capturando-p-225-ginas-web.aspx#comments</comments><description>&lt;p&gt;&lt;img style="display:inline;margin:0px 20px 20px 0px;" src="http://www.todocontenidos.com/images/articles/scrap03.png" align="left" alt="" /&gt; Para practicar, como &lt;a href="http://codekata.pragprog.com/codekata/" target="_blank"&gt;Code Kata&lt;/a&gt; (y también, como prueba de concepto para un proyecto relacionado con &lt;a title="Hacia una Historia Clínica Digital de Código Abierto" href="http://msmvps.com/blogs/lopez/archive/2009/09/29/hacia-una-historia-cl-237-nica-digital-de-c-243-digo-abierto.aspx"&gt;Hacia una Historia Clínica Digital de Código Abierto&lt;/a&gt;), estuve codificando un programa de &lt;a href="http://en.wikipedia.org/wiki/Web_scraping" target="_blank"&gt;Web Scraping&lt;/a&gt;. Pueden bajarse el código completo desde: &lt;a href="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/WebScrappingExample" target="_blank"&gt;Web Scrapping Example&lt;/a&gt; (pensé que en inglés era “scrapping” con doble p, así que quedó por ahora con ese nombre :-)&lt;/p&gt;  &lt;p&gt;La solución, escrita en C#, contiene un proyecto de librería de clases, uno de tests de Visual Studio, y un programa de demostración, del tipo consola. Fue interesante codificar un mini HTML parser (simple, que no contempla todos los casos, sólo los necesarios para el trabajo), que soporta el análisis de páginas mal formadas. El usar TDD (&lt;a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank"&gt;Test-Driven Development&lt;/a&gt;) me permitió ir codificándolo de forma de estar seguro de lo que necesitaba como resultado, y además, que ese resultado fuera el correcto. Ejemplo de test simple:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div id="codeSnippet" style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;     &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;[TestMethod]&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ParseSimpleTag()&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;{&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    HtmlParser parser = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; HtmlParser(&lt;span style="color:#006080;"&gt;&amp;quot;&amp;lt;html&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    HtmlToken token = parser.NextToken();&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    Assert.IsNotNull(token);&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    Assert.AreEqual(HtmlTokenType.Tag, token.TokenType);&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    Assert.AreEqual(&lt;span style="color:#006080;"&gt;&amp;quot;html&amp;quot;&lt;/span&gt;, token.Name);&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    Assert.IsNull(parser.NextToken());&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Para capturar las páginas, usé System.Net.WebClient, con código tan simple como:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div id="codeSnippet" style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; GetContent()&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;{&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    WebClient webclient = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; WebClient();&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; webclient.DownloadString(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.address);&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Como demostración, en el programa de consola, parto de explorar la página:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.nlm.nih.gov/medlineplus/druginfo/meds/a699012.html" target="_blank"&gt;Medline Plus Drugs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lanzando el programa de consola, aparece la salida, capturando algunos cientos de páginas, sobre información de drogas medicinales (efectos, posología, contraindicaciones, etc):&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/scrap02.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Exploro las páginas que apuntan a la información de drogas por letra, obtengo los enlaces a cada droga, traigo el contenido de la página, extraigo la información que me interesa (descartando el principio y el fin de la página) por cada droga. Un ejemplo de página:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/scrap01.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Al final, genero una página de índice:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/scrap04.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Podría implementar un mejor parser de HTML, y algunas operaciones más de extracción de datos. Pero para lo que quería obtener, me bastó. Y fue una buena experiencia de TDD.&lt;/p&gt;

&lt;p&gt;Si usan la información generada, recuerden de leer los términos del sitio original (entiendo que necesitan una autorización para usarlo de forma comercial, no parece que haya problema en capturar los datos en un utilitario no comercial).&lt;/p&gt;

&lt;p&gt;¿Por qué no explorar directamente la web para obtener estos datos? Porque el contexto de la prueba de concepto que me impuse, es que los médicos y enfermeros no tienen acceso a Internet desde todas las máquinas donde van a estar trabajando.&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel “Java” Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1735292" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Programaci_F300_n/default.aspx">Programación</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Code+Katas/default.aspx">Code Katas</category></item><item><title>Twitter para todo: TweetMyPC (y TweetMyMac también)</title><link>http://msmvps.com/blogs/lopez/archive/2009/09/01/twitter-para-todo-tweetmypc-y-tweetmymac-tambi-233-n.aspx</link><pubDate>Tue, 01 Sep 2009 09:55:34 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1719840</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1719840</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/09/01/twitter-para-todo-tweetmypc-y-tweetmymac-tambi-233-n.aspx#comments</comments><description>&lt;p&gt;Una idea que quería explorar es crear un pequeño estándar de &lt;strong&gt;cómo usar mensajes cortos para enviar comandos y recibir respuestas de una aplicación cualquiera&lt;/strong&gt;. Un paso hacia eso, muy ingenioso, es la de TweetMyPc (&lt;a title="http://tweetmypc.codeplex.com/" href="http://tweetmypc.codeplex.com/"&gt;http://tweetmypc.codeplex.com/&lt;/a&gt;). El autor principal es &lt;a href="http://stackoverflow.com/users/12178/shoban" target="_blank"&gt;Shoban&lt;/a&gt;, Microsoft MVP de la India.&lt;/p&gt;  &lt;p&gt;La aplicación es chica, y cuando la ejecutamos en nuestra máquina, ingresamos los datos de nuestra cuenta de Twitter:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/TweetMyPCImage.jpg" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Una vez que arranca la aplicación, comienza a leer nuestros tweets cada 1 minuto. Es conveniente usar una cuenta para cada PC. Desde esa cuenta, desde cualquier otro lugar, podemos enviar comandos como: Shutdown, Hibernate, Lock, y hasta Download, que comienza a bajar un archivo. Una lista parcial de comandos la pueden ver en:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.codegeeks.net/tweetmypc-what-next" href="http://www.codegeeks.net/tweetmypc-what-next"&gt;http://www.codegeeks.net/tweetmypc-what-next&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Si uno saca un Screenshot remoto, la aplicación responde enviando un comando con una URL de la imagen tomada. Este es el tipo de respuesta que tenía en mente en el primer párrafo de este post: &lt;strong&gt;una forma de enviar algo más grande que un mensaje, es mediante una URL&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;La aplicación está escrita en .NET. No vi el código todavía, pero está originalmente &lt;a href="http://tweetmypc.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28234#DownloadId=70382" target="_blank"&gt;escrita en VB.Net&lt;/a&gt; y hay &lt;a href="http://tweetmypc.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28235#DownloadId=70383" target="_blank"&gt;versión en C#&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Tienen también aplicación para &lt;/p&gt;  &lt;p&gt;Otra aplicación del mismo autor:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.codeplex.com/jata" href="http://www.codeplex.com/jata"&gt;http://www.codeplex.com/jata&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Jata is a Google Talk like Twitter Application which was developed using VB.net and Twiteroo Twitter API framework.     &lt;br /&gt;jata automatically checks for new messages periodically. You can post your status right from jata post message screen.      &lt;br /&gt;You can also reply to tweets using jata.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p dir="ltr" style="margin-right:0px;"&gt;Habría que seguir explorando la idea de manejar aplicaciones con mensajes cortos, desde Twitter u otros.&lt;/p&gt;  &lt;p dir="ltr" style="margin-right:0px;"&gt;Nos leemos!&lt;/p&gt;  &lt;p dir="ltr" style="margin-right:0px;"&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1719840" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/VB.NET/default.aspx">VB.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Twitter/default.aspx">Twitter</category></item><item><title>Ejemplos de ASP.NET, capas y Linq</title><link>http://msmvps.com/blogs/lopez/archive/2009/07/23/ejemplos-de-asp-net-capas-y-linq.aspx</link><pubDate>Thu, 23 Jul 2009 10:03:45 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1706460</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1706460</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/07/23/ejemplos-de-asp-net-capas-y-linq.aspx#comments</comments><description>&lt;p&gt;Hace dos semanas, terminé de dar un curso de ASP.NET, con máquinas, en el laboratorio del &lt;a href="http://www.mug.org.ar/" target="_blank"&gt;Microsoft User Group de Argentina&lt;/a&gt;, en Buenos Aires, contando con diez asistentes, con los que tuvimos 30 horas explorando el desarrollo de sitios dinámicos con .NET. Los ejemplos que fuimos desarrollando y otros que bajamos de ejemplos míos, están disponibles para bajarse desde:&lt;/p&gt;  &lt;p&gt;&lt;a title="Material del Curso de ASP.NET en el MUG" href="http://www.ajlopez.net/ReferenciaVe.php?Id=267"&gt;Material del Curso de ASP.NET en el MUG&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;(Siempre pueden bajar lo que tratamos en mis cursos, desde&lt;/p&gt;  &lt;p&gt;&lt;a title="Materiales de Cursos" href="http://www.ajlopez.net/CursosEjemplos.php"&gt;Materiales de Cursos&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;ya sea ASP.NET, .NET, arquitectura, Java, JSP, Spring, Struts, etc… así como las presentaciones que se usaron)&lt;/p&gt;  &lt;p&gt;Hay varios ejemplos para estudiar, que podría explicar más en detalle en algún post, pero vaya ahora una introducción:&lt;/p&gt;  &lt;p&gt;&lt;a title="AjFirstExample" href="http://cid-9f903f3d6db0c176.skydrive.live.com/self.aspx/Examples/DotNet/AjFirstExampleDotNet.zip"&gt;AjFirstExample&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;En este ejemplo&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/aspnetmug01.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;tenemos una base de datos, que pueden instalar usando cualquiera de los dos directorios Sql, y dos soluciones, una en VB.NET y otra en C#.&lt;/p&gt;  &lt;p&gt;En el directorio Sql, tenemos:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/aspnetmug02.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Podemos lanzar la creación de la base con el comando ExecuteAll.cmd, que contiene&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div id="codeSnippet" style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;     &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;@&lt;span style="color:#008000;"&gt;REM  -------------------------------------------------------------&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;@&lt;span style="color:#008000;"&gt;REM  You can change server.&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;@&lt;span style="color:#008000;"&gt;REM  -------------------------------------------------------------&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; sqlServer=%1%&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; &lt;span style="color:#006080;"&gt;&amp;quot;%1%&amp;quot;&lt;/span&gt;==&lt;span style="color:#006080;"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt; sqlServer=(local)&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;call&lt;/span&gt; CreateDatabase %sqlServer%&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#008000;"&gt;rem TBD:&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#008000;"&gt;rem call LinkData %sqlServer%&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#008000;"&gt;rem call InsertData %sqlServer%&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;goto&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;:&lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Si lo invocamos sin parámetros, va a conectarse con nuestro MS SQL Server (local). Si queremos ir contra otra instancia, por ejemplo, contra .\SQLEXPRESS, hay que invocarlo como:&lt;/p&gt;

&lt;p&gt;ExecuteAll.cmd .\SQLEXPRESS&lt;/p&gt;

&lt;p&gt;Crea una base simple, AjFirstExample, con dos tablas, clientes y proveedores, y procedimientos almacenados:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/aspnetmug03.png" alt="" /&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;El ejemplo sigue algunos linemamientos de Patterns &amp;amp; Practices, de Microsoft, como tener separados Business Entities de Business Components. La solución tiene varios proyectos:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/aspnetmug04.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;WebClient es el sitio web. AjFirstExample.Services es una capa de servicios lógicos (no tecnológicos, como podría ser un Web Service), que es un .DLL que se invoca directamente de el sitio web. Es lo que en patrones llamamos una Service Layer. AjFirstExample.Entities contiene entidadas simples, con datos, sin conducta ni persistencia. Está muy orientada al ejemplo, que apenas es un CRUD (Create Read Update Delete) de entidades, fragmento:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div id="codeSnippet" style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;Imports&lt;/span&gt; System.Collections.Generic&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;Imports&lt;/span&gt; AjFirstExample.Entities&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;Imports&lt;/span&gt; AjFirstExample.Business&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;Imports&lt;/span&gt; AjFramework.Data&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;Public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Class&lt;/span&gt; SupplierService&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;Private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Shared&lt;/span&gt; mSupplierComponent &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SupplierComponent&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;Public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Shared&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Sub&lt;/span&gt; Insert(entity &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; Supplier)&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;        mSupplierComponent.Insert(entity)&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;End&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Sub&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;Public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Shared&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Sub&lt;/span&gt; Update(entity &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; Supplier)&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;        mSupplierComponent.Update(entity)&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;End&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Sub&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;Public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Shared&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Sub&lt;/span&gt; Delete(id &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Integer&lt;/span&gt;)&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;        mSupplierComponent.Delete(id)&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;End&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Sub&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;Public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Shared&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Function&lt;/span&gt; GetById(id &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Integer&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; Supplier&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; mSupplierComponent.GetById(id)&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;End&lt;/span&gt; Function&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;AjFirstExample.BusinessComponents tiene lógica de validación antes de grabar o insertar una entidad, y AjFirstExample.Data termina encargándose de la persistencia, usando un DataService, que yo había codificado dentro de algo que uso en mis cursos, AjFramework.&lt;/p&gt;

&lt;p&gt;En las páginas web, es común conversar con el servicio, para tomar y enviar datos a ese proyecto:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div id="codeSnippet" style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;Public&lt;/span&gt; Partial &lt;span style="color:#0000ff;"&gt;Class&lt;/span&gt; Admin_CustomersPage&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;Inherits&lt;/span&gt; System.Web.UI.Page&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;Protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Sub&lt;/span&gt; Page_Load(&lt;span style="color:#0000ff;"&gt;ByVal&lt;/span&gt; sender &lt;span style="color:#0000ff;"&gt;As&lt;/span&gt; System.&lt;span style="color:#0000ff;"&gt;Object&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;ByVal&lt;/span&gt; e &lt;span style="color:#0000ff;"&gt;As&lt;/span&gt; System.EventArgs) &lt;span style="color:#0000ff;"&gt;Handles&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Me&lt;/span&gt;.Load&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;        &lt;span style="color:#008000;"&gt;&amp;#39;Put user code to initialize the page here&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;        &lt;span style="color:#0000ff;"&gt;If&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Not&lt;/span&gt; IsPostBack &lt;span style="color:#0000ff;"&gt;Then&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;            gvwData.DataSource = CustomerService.GetList&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;            gvwData.DataBind()&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;        &lt;span style="color:#0000ff;"&gt;End&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;If&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;End&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Sub&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;End&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;Class&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Este ejemplo lo tienen también en ese mismo .zip implementada en C#. Van a ver que ha sido generada directamente por AjGenesis, el generador de código que uso para armar gran parte de mis ejemplos y del desarrollo del día a día que emprendo:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div id="codeSnippet" style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#008000;"&gt;&amp;#39;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#008000;"&gt;&amp;#39; File generated using AjGenesis&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#008000;"&gt;&amp;#39; http://www.ajlopez.com/ajgenesis&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#008000;"&gt;&amp;#39; http://www.ajlopez.net/ajgenesis&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#008000;"&gt;&amp;#39; Open Source Code Generation Engine&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#008000;"&gt;&amp;#39;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Si tienen que cambiar el string de conexión, deben modificar el web.config del proyecto web, en el sector:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div id="codeSnippet" style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;AjFramework&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Parameters&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Parameter&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;ConnectionString&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;server=.\SQLEXPRESS;database=AjFirstExample;Integrated Security=true&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Parameters&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;AjFramework&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Hay otro ejemplo para bajarse e instalar de la misma manera:&lt;/p&gt;

&lt;p&gt;&lt;a title="AjTest" href="http://cid-9f903f3d6db0c176.skydrive.live.com/self.aspx/Examples/DotNet/AjTestDotNet.zip"&gt;AjTest&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Con las mismas ideas:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/aspnetmug05.png" alt="" /&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;pero con más entidades:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/aspnetmug06.png" alt="" /&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Cada departamento contiene empleados. Los proyectos contienen tareas, y las tareas se pueden asigna a empleados. Cada empleado tiene &amp;quot;Skills”, competencias, y cada competencia tiene empleados. Desde las páginas de administración, pueden ingresar los datos de estas entidades.&lt;/p&gt;

&lt;p&gt;Sin embargo, la relación entre estas entidades, no está en la entidad misma, sino en cómo recuperamos los datos necesarios desde el servicio. En vez de tener dentro de Department una lista de Employee, los empleados de un departamento se obtienen desde código, ejemplo:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div id="codeSnippet" style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Page_Load(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, System.EventArgs e)&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;{&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#008000;"&gt;// Put user code to initialize the page here&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!IsPostBack) {&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;        IdEntity = Convert.ToInt32(Request[&lt;span style="color:#006080;"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;        Entity = DepartmentService.GetById(IdEntity);&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;        dtgDataEmployees.DataSource = EmployeeService.GetByDepartmentEx(IdEntity);&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;           DataBind();&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    }&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Un ejemplo, donde usamos una base similar, pero en el código establecemos las relaciones, está en:&lt;/p&gt;

&lt;p&gt;&lt;a title="AjTestCSharp3Linq.zip" href="http://cid-9f903f3d6db0c176.skydrive.live.com/self.aspx/Examples/DotNet/AjTestCSharp3Linq.zip"&gt;AjTestCSharp3Linq.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Acá usamos Linq2Sql&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/aspnetmug07.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;donde las entidades, generadas por el wizard de Linq2Sql, ya tienen las relaciones incorporadas. Entonces, una vez obtenido un Deparment, podemos pasar a Employees en una simple propiedad que tiene el objecto departamento:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div id="codeSnippet" style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Page_Load(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, System.EventArgs e)&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;{&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#008000;"&gt;// Put user code to initialize the page here&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!IsPostBack) {&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;        LinqDepartmentsService service = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; LinqDepartmentsService();&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;        IdEntity = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Guid(Request[&lt;span style="color:#006080;"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;        Entity = service.GetDepartment(IdEntity);&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;        dtgDataEmployees.DataSource = Entity.Employees;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;           DataBind();&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    }&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Un último ejemplo más, para este post rápido:&lt;/p&gt;

&lt;p&gt;&lt;a title="AjFirstExampleWcfCSharp3.zip" href="http://cid-9f903f3d6db0c176.skydrive.live.com/self.aspx/Examples/DotNet/AjFirstExampleWcfCSharp3.zip"&gt;AjFirstExampleWcfCSharp3.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En este caso, seguimos usando Linq, lo que viaja a la presentación, son mensajes Windows Communication Foundation, hay un sitio web que expone servicios WCF, y de la parte del cliente, código de gateway para llegar a esos servicios:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/aspnetmug08.png" alt="" /&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;En vez de llegar a la presentación las entidades de .Data, de Linq, pasamos mensajes de Data Contract de WCF:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div id="codeSnippet" style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;
    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; AjFirstExample.Services.Contracts&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;{&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.Runtime.Serialization;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    [DataContract]&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Customer&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    {&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;        [DataMember]&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Guid Id { get; set; }&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    &lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;        [DataMember]&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Name { get; set; }&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    &lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;        [DataMember]&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Address { get; set; }&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;    &lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;        [DataMember]&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Notes { get; set; }&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:white;text-align:left;border-bottom-style:none;"&gt;    }&lt;/pre&gt;


    &lt;pre style="padding-right:0px;padding-left:0px;font-size:8pt;padding-bottom:0px;margin:0em;overflow:visible;width:100%;color:black;direction:ltr;border-top-style:none;line-height:12pt;padding-top:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;border-right-style:none;border-left-style:none;background-color:#f4f4f4;text-align:left;border-bottom-style:none;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Bueno, espero que puedan sacar algo útil de estos ejemplo, vean también los archivos de ejemplos que fuimos desarrollando en cada clase.&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel “Java” Lopez
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1706460" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/VB.NET/default.aspx">VB.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Popularidad de Lenguajes de Programación</title><link>http://msmvps.com/blogs/lopez/archive/2009/07/08/popularidad-de-lenguajes-de-programaci-243-n.aspx</link><pubDate>Wed, 08 Jul 2009 09:50:06 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1698705</guid><dc:creator>lopez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1698705</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/07/08/popularidad-de-lenguajes-de-programaci-243-n.aspx#comments</comments><description>&lt;p&gt;Me temo que &lt;a href="http://en.wordpress.com/tag/ajlisp/" target="_blank"&gt;AjLisp&lt;/a&gt; y &lt;a href="http://en.wordpress.com/tag/ajbasic" target="_blank"&gt;AjBasic&lt;/a&gt; lo usamos yo y nadie más… snif… :-). Pero hay lenguajes más populares que esos. Ya es clásica la lista de TIOBE Software:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html" href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"&gt;http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/langpop01.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;donde aparece Java como el lenguaje más popular, lo que no me asombra. Pero sí me llama la atención la popularidad de C y C++, que deben tener su gran uso en el ambiente Unix, Linux, y otros. Como cuarto, encuentro hoy, Julio de 2009, a PHP, que lo entiendo: la mayor parte del código de sitios dinámicos está en PHP, lejos quedaron los años del predominio del venerable Perl. Y recién en sexto y séptimo lugar, está Visual Basic (parece que agrupan el de .NET y el clásico), y C#. Vean que al final de la lista, aparecen lenguajes con mínimos porcentajes, pero aparecen: RPG, Pascal, Abap, Lisp/Scheme. Más abajo, en la misma página encontraran la lista de posición 21 a 50, donde aparecen COBOL, Objective-C, Fortran, Logo, Prolog, Ada (todavía anda por ahí? :-), Scala, Erlang…. y esta es la lista de 51 a 100:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;ABC, AD, Algol, Alpha, Applescript, Beta, Boo, C shell, cg, Clean, Cobra, cT, Curl, Dylan, Eiffel, Euphoria, Factor, Fan, Icon, IDL, Inform, Io, Lingo, MAD, Magic, Maple, Mathematica, MAX/MSP, MOO, MUMPS, Natural, Oberon, Occam, Oz, PL/I, Postscript, PowerBuilder, Progress, Q, R, Revolution, REXX, S-lang, SIGNAL, SPSS, SuperCollider, VBScript, Verilog, VHDL, XSLT&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Notable lista, recomendaría tantos lenguajes de esa lista, simplemente para aprender nuevas formas de programar (notable que aparezca todavía MUMPS, REXX, tendría que ver con más detalle a Io). Esta lista de popularidad se basa en el examen de búsquedas en Google, hace un tiempo pasaron a agregar MSN y Yahoo.&lt;/p&gt;  &lt;p&gt;Pero en estos días, encontré otra página:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://langpop.com/" href="http://langpop.com/"&gt;http://langpop.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/langpop02.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;con información de ranking de popularidad, pero con agrupadas con distintas fuentes, como Yahoo Search, search en Google Code, Freshmeat, Craiglist, Amazon.&lt;/p&gt;  &lt;p&gt;En lo que veo hoy ahí, julio de 2009, según Yahoo Search C es más popular que Java. Pero para Craiglist, primero PHP, segundo SQL (!!!), en Amazon ganan C, C++ y C#, por encima de Java. Y así, noto dispersión de los resultados, dependiendo de la fuente.&lt;/p&gt;  &lt;p&gt;La popularidad de un lenguaje importa. No tanto para entender el lenguaje (muchos lenguajes “boutique” tienen interesantes conceptos, a estudiar con detalle), sino para tener una idea de qué tecnología ha sido adoptada por la comunidad, pero habría que ver más allá: por qué la eligieron, y en qué tipo de proyectos. Dudo que haya muchas aplicaciones desktop, en PHP.&lt;/p&gt;  &lt;p&gt;Resumen: gran cantidad de lenguajes, hay lenguajes viejos, desde COBOL y Smalltalk, y más “nuevos” como Boo, Ruby, Python. Y `cuatros grandes grupos: Java, C/C++, lenguajes .NET (VB.NET, C#), PHP, como claros grupos líderes.&lt;/p&gt;  &lt;p&gt;Pienso que, como desarrolladores de software, debemos tener contacto con esos cuatro grupos, y además, con alguno de los “otros”, para aprender otras ideas y formas de programar.&lt;/p&gt;  &lt;p&gt;No&amp;#160; me enojo si intentan ver &lt;a href="http://en.wordpress.com/tag/ajlisp" target="_blank"&gt;AjLisp&lt;/a&gt; o &lt;a href="http://en.wordpress.com/tag/ajbasic" target="_blank"&gt;AjBasic&lt;/a&gt;… :-)&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1698705" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/PHP/default.aspx">PHP</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Smalltalk/default.aspx">Smalltalk</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjLisp/default.aspx">AjLisp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjBasic/default.aspx">AjBasic</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category></item><item><title>Primer ejemplo con NHibernate 2.x</title><link>http://msmvps.com/blogs/lopez/archive/2009/06/04/first_2D00_nhibernate_2D00_2_2D00_x_2D00_example.aspx</link><pubDate>Thu, 04 Jun 2009 09:17:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1693849</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1693849</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/06/04/first_2D00_nhibernate_2D00_2_2D00_x_2D00_example.aspx#comments</comments><description>&lt;p&gt;Estuve trabajando creando una soluci&amp;oacute;n .NET que contiene un ejemplo m&amp;iacute;nimo de NHibernate 2.x. Estoy usando la distribuci&amp;oacute;n binaria NHibernate GA 2.0.1, siguiendo las instrucciones del manual de referencia.&lt;/p&gt;
&lt;p&gt;Pueden bajarse el c&amp;oacute;digo fuente de la soluci&amp;oacute;n de mi Skydrive:&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="http://cid-9f903f3d6db0c176.skydrive.live.com/self.aspx/Examples/NHibernate/NHibernateExample1.zip"&gt;NHibernateExample1.zip&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Estuve usando la documentaci&amp;oacute;n en l&amp;iacute;nea de&lt;/p&gt;
&lt;p&gt;&lt;a href="http://nhforge.org/doc/nh/en/" title="http://nhforge.org/doc/nh/en/"&gt;http://nhforge.org/doc/nh/en/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;y arm&amp;eacute; el mismo manual en formato .pdf, usando comandos del trunk de SVN:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://nhibernate.svn.sourceforge.net/svnroot/nhibernate" title="https://nhibernate.svn.sourceforge.net/svnroot/nhibernate"&gt;https://nhibernate.svn.sourceforge.net/svnroot/nhibernate&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si quieren, pueden bajar el manual en .pdf de este enlace:&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="http://www.todocontenidos.com/images/articles/nhibernate-reference.pdf"&gt;nhibernate-reference.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La soluci&amp;oacute;n contiene dos proyectos: una librer&amp;iacute;a de clases, y una aplicaci&amp;oacute;n de consola:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/nhibernateex1-02.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;El dominio s&amp;oacute;lo contiene una clase, Cat (estoy siguiendo el primer ejemplo que se describe en la documentaci&amp;oacute;n):&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;namespace NHibernateExample1.Domain
{
    public class Cat
    {
        private string id;
        private string name;
        private char sex;
        private float weight;

        public Cat()
        {
        }
        public virtual string Id
        {
            get { return id; }
            set { id = value; }
        }

        public virtual string Name
        {
            get { return name; }
            set { name = value; }
        }

        public virtual char Sex
        {
            get { return sex; }
            set { sex = value; }
        }

        public virtual float Weight
        {
            get { return weight; }
            set { weight = value; }
        }
    }
}

Hay un recurso embebido que describe el mapeo Cat.hbm.xml:&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;
&amp;lt;hibernate-mapping xmlns=&amp;quot;urn:nhibernate-mapping-2.2&amp;quot;
namespace=&amp;quot;NHibernateExample1.Domain&amp;quot; assembly=&amp;quot;NHibernateExample1.Domain&amp;quot;&amp;gt;
  &amp;lt;class name=&amp;quot;Cat&amp;quot; table=&amp;quot;Cats&amp;quot;&amp;gt;
    &amp;lt;!-- A 32 hex character is our surrogate key. It&amp;#39;s automatically
generated by NHibernate with the UUID pattern. --&amp;gt;
    &amp;lt;id name=&amp;quot;Id&amp;quot;&amp;gt;
      &amp;lt;column name=&amp;quot;CatId&amp;quot; sql-type=&amp;quot;char(32)&amp;quot; not-null=&amp;quot;true&amp;quot;/&amp;gt;
      &amp;lt;generator class=&amp;quot;uuid.hex&amp;quot; /&amp;gt;
    &amp;lt;/id&amp;gt;
    &amp;lt;!-- A cat has to have a name, but it shouldn&amp;#39; be too long. --&amp;gt;
    &amp;lt;property name=&amp;quot;Name&amp;quot;&amp;gt;
      &amp;lt;column name=&amp;quot;Name&amp;quot; length=&amp;quot;16&amp;quot; not-null=&amp;quot;true&amp;quot; /&amp;gt;
    &amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;quot;Sex&amp;quot; /&amp;gt;
    &amp;lt;property name=&amp;quot;Weight&amp;quot; /&amp;gt;
  &amp;lt;/class&amp;gt;
&amp;lt;/hibernate-mapping&amp;gt;&lt;/pre&gt;
&lt;p&gt;Hay un ExecuteAll.cmd en el directorio Sql, que crea la base de datos a usar (pueden darle como par&amp;aacute;metro el servidor de MS SQL Server a usar,&amp;nbsp; .\SQLEXPRESS es el valor asumido):&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/nhibernateex1-03.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;La aplicaci&amp;oacute;n de consola es simple: configura NHibernate, obtiene una sesi&amp;oacute;n, inserta nuevos objetos en una transacci&amp;oacute;n, ejecuta una consulta, y lista el resultado:&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;        static void Main(string[] args)
        {
            ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory();

            ISession session = sessionFactory.OpenSession();
            ITransaction tx = session.BeginTransaction();

            Cat cat;

            cat = new Cat() { Name = &amp;quot;Moe&amp;quot;, Sex = &amp;#39;M&amp;#39;, Weight = 9.0f };

            session.Save(cat);

            cat = new Cat() { Name = &amp;quot;Larry&amp;quot;, Sex = &amp;#39;M&amp;#39;, Weight = 8.5f };

            session.Save(cat);

            cat = new Cat() { Name = &amp;quot;Sue&amp;quot;, Sex = &amp;#39;F&amp;#39;, Weight = 7.5f };

            session.Save(cat);

            tx.Commit();

            IQuery query = session.CreateQuery(&amp;quot;select c from Cat as c where c.Sex = :sex&amp;quot;);

            query.SetCharacter(&amp;quot;sex&amp;quot;, &amp;#39;M&amp;#39;);

            foreach (Cat kitty in query.Enumerable())
                System.Console.Out.WriteLine(&amp;quot;Male Cat: &amp;quot; + kitty.Name);

            session.Close();

            System.Console.ReadLine();
        }&lt;/pre&gt;
&lt;p&gt;Ejecutando la aplicaci&amp;oacute;n de consola se inserta en la base estos datos:&lt;img src="http://www.todocontenidos.com/images/articles/nhibernateex1-01.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;El ejemplo es simple. Ahora que est&amp;aacute; funcionando con NHibernate 2.0, pienso actualizar mis templates de AjGenesis para usar esa versi&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;No dejen de visitar el sitio de comunidad de NHibernate, para conseguir m&amp;aacute;s informaci&amp;oacute;n:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://nhforge.org"&gt;http://nhforge.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si tienen dudas sobre NHibernate, pueden preguntar en el grupo en espa&amp;ntilde;ol:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://groups.google.com/group/NHibernate-Hispano" title="NHibernate-Hispano"&gt;NHibernate-Hispano&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1693849" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category></item><item><title>Presentando AjCat</title><link>http://msmvps.com/blogs/lopez/archive/2009/04/29/presenting_2D00_ajcat.aspx</link><pubDate>Wed, 29 Apr 2009 10:24:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1691539</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1691539</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/04/29/presenting_2D00_ajcat.aspx#comments</comments><description>&lt;p&gt;Hace algo m&amp;aacute;s de un mes, estuve trabajando en un int&amp;eacute;rprete del lenguaje Cat:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cat-language.com/" title="The Cat Programming Language"&gt;The Cat Programming Language&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Cat is a functional stack-based programming language inspired by the &lt;/em&gt;&lt;a href="http://www.latrobe.edu.au/philosophy/phimvt/"&gt;&lt;em&gt;Joy programming language&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. The primary differences is that Cat provides a static type system with type inferencing (like ML or Haskell), and a term rewriting macro language extension language called &lt;/em&gt;&lt;a href="https://ajlopez.wordpress.com/wp-admin/metacat.html"&gt;&lt;em&gt;MetaCat&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Cat is a high-level intermediate language translation that can also be used as a stand alone language for simple application development. In this way it occupies a similar niche to PostScript. Cat is also an appropriate language for teaching of basic programming concepts. &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://todocontenidos.com/images/articles/ajcat01.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Si no conocen el lenguaje Cat, recomiendar&amp;iacute;a leer:&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="http://www.cat-language.com/tutorial.html"&gt;Cat Tutorial&lt;/a&gt; &lt;br /&gt;&lt;a target="_blank" href="http://www.cat-language.com/manual.html"&gt;Cat Specification&lt;/a&gt; &lt;br /&gt;&lt;a target="_blank" href="http://www.cat-language.com/primitives.html"&gt;Cat Primitives&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Publiqu&amp;eacute; el c&amp;oacute;digo como parte de mi proyecto Code Katas en Google Code. El nombre que us&amp;eacute; es AjCat:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjCat" title="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjCat"&gt;http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjCat&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La soluci&amp;oacute;n tiene tres proyectos:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://todocontenidos.com/images/articles/ajcat02.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;La actual implementaci&amp;oacute;n no es completa. Solo soporta enteros, todav&amp;iacute;a no soporta objetos .NET, y no hay primitivas de gr&amp;aacute;ficos. Pero est&amp;aacute; implementado gran parte de las primitivas y funciones definidas en Cat.&lt;/p&gt;
&lt;p&gt;Corriendo el programa de consola, pueden ingresar y evaluar expresiones:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://todocontenidos.com/images/articles/ajcat05.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Este c&amp;oacute;digo est&amp;aacute; dedicado a &lt;a href="http://weblogs.shockbyte.com.ar/"&gt;Rodolfo Finocchieti&lt;/a&gt; (&lt;a href="http://twitter.com/rodolfof"&gt;@rodolfof&lt;/a&gt; en Twitter) quien me dej&amp;oacute; un comentario ac&amp;aacute; en este blog, coment&amp;aacute;ndome de este lenguaje Cat, una idea fascinante.&lt;/p&gt;
&lt;p&gt;Los tests est&amp;aacute;n en verdes:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://todocontenidos.com/images/articles/ajcat03.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Y hay un buen code coverage&lt;/p&gt;
&lt;p&gt;&lt;img src="http://todocontenidos.com/images/articles/ajcat04.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Como siempre, me divert&amp;iacute; escribiendo este c&amp;oacute;digo.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez &lt;br /&gt;&lt;a href="http://www.ajlopez.com/"&gt;http://www.ajlopez.com/&lt;/a&gt; &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enjoying &lt;a href="http://ajlopez.zoomblog.com/archivo/2009/04/08/eric-Clapton-Everyday-I-Have-the-Blues.html" title="Eric Clapton Everyday I Have the Blues Live"&gt;Eric Clapton Everyday I Have the Blues Live&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1691539" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Programaci_26002300_243_3B00_n+Funcional/default.aspx">Programaci&amp;#243;n Funcional</category></item><item><title>CodeRun plataforma de desarrollo en línea</title><link>http://msmvps.com/blogs/lopez/archive/2009/03/24/coderun-plataforma-de-desarrollo-en-l-237-nea.aspx</link><pubDate>Tue, 24 Mar 2009 11:54:50 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1680972</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1680972</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/03/24/coderun-plataforma-de-desarrollo-en-l-237-nea.aspx#comments</comments><description>&lt;p&gt;El bueno de &lt;a href="http://blog.salias.com.ar/" target="_blank"&gt;Martín Salías&lt;/a&gt; (@MartinSalias) me avisa de este sitio y aplicación notable:&lt;/p&gt; &lt;p&gt;&lt;a title="http://www.coderun.com/" href="http://www.coderun.com/"&gt;http://www.coderun.com/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/coderun03.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Pueden registrarse, el servicio básico es gratuito.&lt;/p&gt; &lt;p&gt;Al ingresar, se encuentran con algo parecido al Visual Studio:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/coderun02.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Si vamos a crear un nuevo proyecto, vemos los distintos tipos de soluciones soportadas:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/coderun01.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Hasta tienen para desarrollar una aplicación para Facebook. Eligiendo el ejemplo de Hello World, clásico desde el Kernighan y Ritchie, obtenemos:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/coderun04.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Lo podemos compilar y ejecutar:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/coderun05.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Era algo que yo estaba esperando: tener un entorno de desarrollo en línea (no solamente una máquina a la que pueda acceder, sino todo instalado para cumplir con una función). Veremos hasta dónde llega esta tendencia, pero veo que tendremos cada vez más poder de procesamiento, sin tener que actualizar el hardware local o el software nuestro. En vez de menú de programas, iremos a favoritos en el browser.&lt;/p&gt; &lt;p&gt;Ya me veo programando un Code Kata desde un ciber, como en mis tiempos de PHP ... ;-)&lt;/p&gt; &lt;p&gt;Debe haber un Eclipse en línea, ¿conocen algún enlace?&lt;/p&gt; &lt;p&gt;Nos leemos!&lt;/p&gt; &lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com/"&gt;http://www.ajlopez.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1680972" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Test-driven development en acción, usando Visual Studio</title><link>http://msmvps.com/blogs/lopez/archive/2009/03/18/test-driven-development-en-acci-243-n-usando-visual-studio.aspx</link><pubDate>Wed, 18 Mar 2009 09:09:42 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1678959</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1678959</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/03/18/test-driven-development-en-acci-243-n-usando-visual-studio.aspx#comments</comments><description>&lt;p&gt;Estoy preparando una charla para el jueves de la semana que viene, 26 de Marzo, en el &lt;a href="http://www.mug.org.ar/"&gt;Microsoft User Group&lt;/a&gt; de Argentina. Pueden inscribirse en:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.mug.org.ar/Eventos/3234.aspx" target="_blank"&gt;MEDIA JORNADA &amp;quot;Test-driven development en acción, usando Visual Studio&amp;quot;&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/mugtdd.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;El horario es de 18:30 a 21:30. La idea es ir armando ejemplos usando los principios de TDD, con código que muestre:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Documentar el código con tests, en vez de en papel  &lt;li&gt;Usar listas de test para generar requerimientos explícitos  &lt;li&gt;Refactorear y mejorar el diseño del código  &lt;li&gt;Test bajo una UI delgada  &lt;li&gt;Test para cambios incrementales, minimizando la depuración  &lt;li&gt;Entregar software que sea verificable y robusto&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Lo que veremos estará basado en .NET y Visual Studio, pero se puede aplicar a otros entornos, lenguajes y tecnologías. Las ideas de base son las mismas.&lt;/p&gt; &lt;p&gt;Como siempre, preparar una charla sirve para aclarar los puntos que uno va aplicando en el día a día. Explicar algo, nos permite entenderlo mejor.&lt;/p&gt; &lt;p&gt;Es gratis PARA LOS SOCIOS DEL MUG. Los demás, ¿qué esperan para asociarse? ;-)&lt;/p&gt; &lt;p&gt;Como en otras ocasiones, publicaré en mi sitio el material que utilice en el curso, y probablemente, aparecerán posts por este blog, explicando algunos puntos.&lt;/p&gt; &lt;p&gt;¿Sugerencias a incluir en el temario? ¿Otros temas interesantes para armar una charla-serie de posts?&lt;/p&gt; &lt;p&gt;(Gracias a la gente del MUG, en especial a Gustavo Bachrach, que me han pedido un post para publicar en la revista que entregan a los socios).&lt;/p&gt; &lt;p&gt;Nos leemos!&lt;/p&gt; &lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com/"&gt;http://www.ajlopez.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1678959" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Cursos/default.aspx">Cursos</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/VB.NET/default.aspx">VB.NET</category></item><item><title>TDD and Code Kata: Writing a Lexer for AjRuby</title><link>http://msmvps.com/blogs/lopez/archive/2009/03/12/tdd_2D00_and_2D00_code_2D00_kata_2D00_writing_2D00_a_2D00_lexer_2D00_for_2D00_ajruby.aspx</link><pubDate>Thu, 12 Mar 2009 05:11:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1677718</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1677718</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/03/12/tdd_2D00_and_2D00_code_2D00_kata_2D00_writing_2D00_a_2D00_lexer_2D00_for_2D00_ajruby.aspx#comments</comments><description>&lt;p&gt;Muchas veces, escribo programas tipo code kata, para entrenarme en algún tema de desarrollo de software. En estos últimos meses, escribí varios mini intérpretes, usando TDD, code coverage, y C#. La semana pasada, estuve trabajando en el lanzamiento de otro pet project, AjRuby. El punto de inicio: el analizador léxico, el lexer.&lt;/p&gt;  &lt;p&gt;Un lexer es un programa que analiza el código fuente de un programa, y retorna sus tokens, las “palabras” que componen el programa. En el caso de AjRuby, escribí un lexer que sigue la gramática de Ruby. No está completo aún, pero funciona.&lt;/p&gt;  &lt;p&gt;Pueden ver el progreso del proyecto, en el repositorio de Google Code:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjRuby" href="http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjRuby"&gt;http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjRuby&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;La solución tiene un proyecto de librería de clases, y otro de tests:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajruby02.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Hay una clase Token, que representa cada token:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:3556dfda-95db-4216-8c88-ba67a9266e51" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;   &lt;pre style="background-color:white;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Token
    {
        &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; Value { &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }

        &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; TokenType TokenType { &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;El TokenType es una enumeración:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:b030a353-46ec-4f15-be42-fe729deaca08" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;
  &lt;pre style="background-color:white;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;enum&lt;/span&gt;&lt;span style="color:#000000;"&gt; TokenType
    {
        Name,
        Integer,
        Real,
        Boolean,
        String,
        Operator,
        Separator
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Hay una clase LexerTest.cs, conteniendo tests como:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:3acb3099-f7eb-417e-b132-9927cd84a1f9" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;
  &lt;pre style="background-color:white;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;        [TestMethod]
        &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; ShouldProcessName()
        {
            Lexer lexer &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Lexer(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;name&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);

            Token token;

            token &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; lexer.NextToken();

            Assert.IsNotNull(token);
            Assert.AreEqual(TokenType.Name, token.TokenType);
            Assert.AreEqual(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;name&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, token.Value);

            token &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; lexer.NextToken();

            Assert.IsNull(token);
        }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Hay un test para cada tipo de token a ser procesado. Otro ejemplo:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:9b11e40f-18a3-4bce-9d93-6d349df8b74d" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;
  &lt;pre style="background-color:white;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;        [TestMethod]
        &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; ShouldProcessNameWithInitialUnderscore()
        {
            Lexer lexer &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Lexer(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;_name&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);

            Token token;

            token &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; lexer.NextToken();

            Assert.IsNotNull(token);
            Assert.AreEqual(TokenType.Name, token.TokenType);
            Assert.AreEqual(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;_name&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, token.Value);

            token &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; lexer.NextToken();

            Assert.IsNull(token);
        }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Escribí los tests usando ideas TDD: escribir el test, compilar con error, arreglar los problemas de compilación, ejecutar los tests en rojo, arreglarlos, conseguir el verde para los tests. No estuve haciendo tanto refactoring. El código merece algún refactor, pero por ahora, estoy tratando de conseguir un lexer que trabaje. Los tests quedaron en verde:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajruby01.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Mi objetivo es tener más del 80% de code coverage, en cualquier momento del desarrollo del proyecto:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajruby03.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Es bueno escribir algo sólo por diversión y aprendizaje. Para mí, es parte de la mejora continua que todo desarrollador de software debe perseguir.&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1677718" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C_26002300_243_3B00_digo+Abierto/default.aspx">C&amp;#243;digo Abierto</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category></item><item><title>Web Crawler distribuido usando AjMessages</title><link>http://msmvps.com/blogs/lopez/archive/2009/03/10/web-crawler-distribuido-usando-ajmessages.aspx</link><pubDate>Tue, 10 Mar 2009 01:07:04 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1677100</guid><dc:creator>lopez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1677100</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/03/10/web-crawler-distribuido-usando-ajmessages.aspx#comments</comments><description>&lt;p&gt;En Enero pasado, actualicé mi proyecto AjMessages para que soporte comunicación usando DSS/CCR&amp;nbsp;y Windows Communication Foundation. AjMessage puede ejecutarse de forma distribuida, enviando mensajes desde un nodo lógico a otro. Los nodos lógicos pueden albergarse en una o más máquinas física. Más información sobre AjMessages en:&lt;/p&gt; &lt;p&gt;&lt;a title="AjMessages- a message processor" href="http://ajlopez.wordpress.com/2007/10/18/ajmessages-a-message-processor/"&gt;AjMessages- a message processor&lt;/a&gt;&lt;br /&gt;&lt;a href="http://ajlopez.wordpress.com/2008/10/08/distributed-applications-with-ajmessages-using-dssccr/" target="_blank"&gt;Distributed Applications with AjMessages using DSS/CCR&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2008/10/10/aplicaciones-distribuidas-con-ajmessages-usando-dss-ccr.aspx" target="_blank"&gt;Aplicaciones Distribuidas con AjMessages usando DSS/CCR&lt;/a&gt;&lt;br /&gt;&lt;a title="AjMessages- hacia un procesador de mensajes" href="http://msmvps.com/blogs/lopez/archive/2007/10/22/ajmessages-hacia-un-procesador-de-mensajes.aspx"&gt;AjMessages- hacia un procesador de mensajes&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Pueden descargar el código fuente desde&lt;/p&gt; &lt;p&gt;&lt;a title="ajmessages" href="http://www.codeplex.com/ajmessages"&gt;http://www.codeplex.com/ajmessages&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Tenía la idea de escribir un procesador de mensajes distribuidos. Hace unos años, escribí mi primer intento, llamado AjServer&lt;/p&gt; &lt;p&gt;&lt;a title="Hacia el AjServer" href="http://msmvps.com/blogs/lopez/archive/2006/07/20/105318.aspx"&gt;Hacia el AjServer&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Luego, encontré al proyecto &lt;a title="Fabriq" href="http://ajlopez.wordpress.com/2007/10/14/remember-fabriq/"&gt;Fabriq&lt;/a&gt;, estudiando sus ideas e implementación. En ese proyecto,&amp;nbsp;hay manejadores (handlers) lógicos de mensajes, que pueden instalarse de modo distribuido, de forma transparente, cambiando la información de configuración:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/fabriq01.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;En el&amp;nbsp;2007, escribí la primera versión de AjMessages, como prueba de concepto: pude reproducir bastante de las ideas de Fabriq, y a la vez, elevar el nivel de abstracción de algunos puntos, para conseguir mayor flexibilidad. Fabriq estaba más orientado a SOA. AjMessages se orienta a mensajes arbitrarios, que coordinados, pueden funcionar en una aplicación en grilla.&lt;/p&gt; &lt;p&gt;La solución actual de AjMessages es:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/AjMessages01.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Hay un proyecto núcleo, y dos proyectos de transporte: uno para soporte de WCF, y otro que se basa en DSS/CCR (tecnologías de Microsoft Robotics). Si no tienen DSS/CCR instalado, pueden remover los proyectos que lo referencia. El núcleo de AjMessages está lib de dependencias de esas tecnologías.&lt;/p&gt; &lt;p&gt;AjMessages.SampleApp contiene un simple manejador de mensajes: un decrementador de enteros, que toma un mensaje de entrada, con un contenido entero, lo decrementa, y produce un nuevo mensaje.&lt;/p&gt; &lt;p&gt;En cambio,&amp;nbsp;AjMessages.WebCrawler implementa&amp;nbsp;el mensaje y manejadores de mensajes para armar un web crawler distribuido. Pueden ejecutarlo desde una sola máquina, o en varias.&lt;/p&gt; &lt;p&gt;Cara AjMessages tiene:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Body&lt;/strong&gt;: un contenido arbitrario&lt;br /&gt;&lt;strong&gt;Headers&lt;/strong&gt;: información adicional, por clave/valor.&lt;br /&gt;&lt;strong&gt;Action&lt;/strong&gt;: describe el destino del mensaje, usando un patrón Aplicación/Nodo/Acción&lt;/p&gt; &lt;p&gt;(más detalle en &lt;a title="AjMessages- a message processor" href="http://ajlopez.wordpress.com/2007/10/18/ajmessages-a-message-processor/"&gt;&lt;a title="AjMessages- hacia un procesador de mensajes" href="http://msmvps.com/blogs/lopez/archive/2007/10/22/ajmessages-hacia-un-procesador-de-mensajes.aspx"&gt;AjMessages- hacia un procesador de mensajes&lt;/a&gt;&lt;/a&gt;)&lt;/p&gt; &lt;p&gt;Exploremos el ejemplo de web crawler. Esta aplicación está compuesta de nodos, que pueden ser orquestado para visitar una página web, tomar de esa página todos los enlaces relacionados, y volver a tomar esas páginas. Para que no sea un proceso infinito, la visita de páginas se limita al sitio inicial, y hasta un nivel de profundidad. La aplicación puede ser descripta lógicamente con este diagrama:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/webcrawler01.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;El primer mensaje se envía al nodo Controller, a su acción Dispatch. Ese primer mensaje contiene la dirección de la página a visitar. El mensaje es enriquecido, y pasado al nodo Controller, acción Resolve. Este nodo está a cargo de mantener la lista de páginas ya visitadas, y de controlar la profundidad de exploración. Si el enlace recibido es aprobado, entonces el mensaje es enviado al nodo Downloader, acción Download. El contenido de la página es recuperado, agregado al mensaje, y reenviado al nodo Harvester, a su acción&amp;nbsp;Harvest. Esta acción analiza el contenido de la página, y emite&amp;nbsp;varios mensajes, uno por&amp;nbsp;cada enlace encontrado. El receptor de esos nuevos enlaces es el nodo Resolver, en su acción Resolve. Así, el proceso continua hasta visitar todas las páginas (con un límite en la profundidad a explorar).&lt;/p&gt; &lt;p&gt;Esta aplicación se puede describir en un archivo de configuración XML, como por ejemplo:&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:a3a0de01-755f-4538-96e5-153042196cee" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;AjMessages&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Dispatcher&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Handler &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;DispatcherHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;AjMessages.WebCrawler.Handlers.Dispatcher, AjMessages.WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Action &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Dispatch&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Handler&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;DispatcherHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Harvester&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Handler &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;HarvesterHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;AjMessages.WebCrawler.Handlers.Harvester, AjMessages.WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Action &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Harvest&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Handler&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;HarvesterHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Downloader&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Handler &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;DownloaderHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;AjMessages.WebCrawler.Handlers.Downloader, AjMessages.WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Action &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Download&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Handler&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;DownloaderHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Controller&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Handler &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;ResolverHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;AjMessages.WebCrawler.Handlers.Resolver, AjMessages.WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Action &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Resolve&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Handler&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;ResolverHandler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;AjMessages&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Un aplicación, entonces, está compuesta de nodos lógicos. Cada nodo puede ser visto como una clase lógica. Cada nodo puede manejar acciones, que son los puntos destinos de los mensajes. Una acción puede&amp;nbsp;estar compuesta de uno o varios pasos. Este es el punto de extensibilidad de la aplicación: deben proveer los pasos, el manejador de mensaje, y escribir el archivo de configuración que orquestre el procesamiento de los mensajes.&lt;/p&gt;
&lt;p&gt;Pero una cosa es la aplicación, y otra es su distribución en máquinas físicas. Pueden tener dos hosts, e instalar diferentes nodes en cada uno:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/webcrawler02.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;En este diagrama, el Dispatcher y el Resolver están en un hosts, mientras que el Downloader y el Harvester están en otro. Pero Uds. pueden poner Harverstes en cada hosts,&amp;nbsp;o en veinte máquinas.&amp;nbsp;Queda en&amp;nbsp;Uds. cómo distribuir la carga del trabajo. Cuando un mensaje&amp;nbsp;es enviado&amp;nbsp;a un destino (Aplicación/Nodo/Acción),&amp;nbsp; AjMessage lo reenvía a un host apropiado, que contenga un nodo capaz de procesar el mensaje.&lt;/p&gt;
&lt;p&gt;La distribución de nodos lógicos en un host físico se define via configuración, por ejemplo:&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:17c1d13e-1e21-4d39-a87d-3e3a2b0a07a4" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;AjMessages&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Host &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Server1&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Address&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;http://localhost:50002/AjMessages&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Activate&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;AjMessages&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Administration&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Controller&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Dispatcher&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Harvester&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Downloader&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Host&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;

  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Host &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Server2&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Address&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;http://localhost:50003/AjMessages&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;AjMessages&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Administration&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;WebCrawler&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Dispatcher&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Harvester&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Node &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Downloader&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Host&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;AjMessages&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Ejecutando el ejemplo Web Crawler&lt;/h3&gt;
&lt;p&gt;Pueden probar el programa, lanzando dos hosts, en la misma máquina. Hay que ejecutar el programa de consola AjMessage.Console. Al comenzar esta aplicación, podemos ingresar el comando&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;fork&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Este comando lanza un segundo host. Ahora, podemos configurar los dos hosts. En el primero, ingresamos:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;load ConfigurationServer1.xml&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Este archivo carga la aplicación AjMessage inicial (es una aplicación más dentro de &amp;quot;la grilla&amp;quot;), y define un endpoint WCF para escuchar mensajes de otros posibles hosts. Ahora, en la misma consola, ingresamos:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;load ConfigurationWebCrawler.xml&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Este comando carga la definición de la aplicación Web Crawler, con sus nodos lógicos (no hay información de deploy todavía). El tercer comando, define la distribución física de hosts:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;load ConfigurationWebCrawlerNode1.xml&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Ahora, volvamos a la segunda consola. Ahí, ingresamos los comandos:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;load ConfigurationServer2.xml&lt;br /&gt;load ConfigurationWebCrawler.xml&lt;br /&gt;load ConfigurationWebCrawlerNode2.xml&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Estamos listos para lanzar el primer web crawling. Vamos a la primera consola, e ingresamos:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;send WebCrawler/Dispatcher/Dispatch &lt;/font&gt;&lt;a href="http://ajlopez.zoomblog.com"&gt;&lt;font face="Consolas"&gt;http://ajlopez.zoomblog.com&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El programa comienza a trabajar, en AMBAS consolas. Una típica salida de la primera consola:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/webcrawler03.png" alt="" /&gt; &lt;/p&gt;
&lt;h3&gt;Próximos pasos&lt;/h3&gt;
&lt;p&gt;Debería arreglar algunos problemas en el transporte DSS/CCR (actualmente, puede ejecutar una aplicación simple como el decrementador de enteros, pero no con el web crawler). Dos puntos para implementar:&lt;/p&gt;
&lt;p&gt;- Configuración remota de nodos&lt;br /&gt;- Distribución de los manejadores de mensajes (sus&amp;nbsp;.dlls)&amp;nbsp;a los nodos&amp;nbsp;remotos&lt;br /&gt;- Una configuración para todos los nodos (ahora, cada nodo es configurado separadamente)&lt;/p&gt;
&lt;p&gt;Comencé un experimento con un proceso más abstracto de mensajes, que quisiera que pudiera implementar casos de uso como:&lt;/p&gt;
&lt;p&gt;- Un simple hello world&lt;br /&gt;- El ejemplo de decrementar enteros&lt;br /&gt;- Web crawler distribuido&lt;br /&gt;- Una especie de Enterprise Service Bus&lt;/p&gt;
&lt;p&gt;Pueden ver mis primeros pasos en:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjProcessor" href="http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjProcessor"&gt;http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjProcessor&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Todavía en desarrollo.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com/"&gt;http://www.ajlopez.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1677100" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjMessages/default.aspx">AjMessages</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Concurrency+and+Coordination+Runtime/default.aspx">Concurrency and Coordination Runtime</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Decentralized+Software+Services/default.aspx">Decentralized Software Services</category></item><item><title>Presentando AjLambda: implementación de Cálculo Lambda en C#</title><link>http://msmvps.com/blogs/lopez/archive/2009/02/26/presentando-ajlambda-implementaci-243-n-de-c-225-lculo-lambda-en-c.aspx</link><pubDate>Thu, 26 Feb 2009 08:19:43 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1674015</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1674015</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/02/26/presentando-ajlambda-implementaci-243-n-de-c-225-lculo-lambda-en-c.aspx#comments</comments><description>&lt;p&gt;Estuve trabajando en my&amp;nbsp;&amp;quot;code kata&amp;quot; AjLambda, una implementación de Cálculo Lambda escrita en C#:&lt;/p&gt; &lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjLambda" href="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjLambda"&gt;http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjLambda&lt;/a&gt;&lt;/p&gt; &lt;p&gt;(Si no conoce el cálculo lambda, hay enlaces sobre el tema al final de este post)&lt;/p&gt; &lt;p&gt;La solución es simple, contiene tres proyectos:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajlambdasln.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Es una librería núcleo, &lt;strong&gt;AjLambda&lt;/strong&gt;, un proyecto de test &lt;strong&gt;AjLambda.Tests&lt;/strong&gt; y un programa de consola &lt;strong&gt;AjLambda.Console&lt;/strong&gt; para ejecutar. El núcleo tiene unas pocas clases principales:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajlambdacd.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Expression&lt;/strong&gt; es la clase base abstracta. &lt;strong&gt;.Reduce&lt;/strong&gt;&amp;nbsp;es el método que implementa la reducción de una expresión. &lt;strong&gt;.Replaces &lt;/strong&gt;se usa para cambiar una variable por otra. Algunas veces, es necesario elegir un nuevo nombre para una variable, que no colisione con otros nombres de variables libres. &lt;strong&gt;.FreeVariables &lt;/strong&gt;es el método para obtener la lista de variables libres en una expresión. Por ejemplo, en la expresión lambda:&lt;/p&gt; &lt;p&gt;&lt;font face="Consolas"&gt;\x.xy&lt;/font&gt;&lt;/p&gt; &lt;p&gt;x e y son variables, pero y es una variable libre, mientras que x es un parámetro ligado.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Variable&lt;/strong&gt; expresa una variable (una letra minúscula, en esta implementación). &lt;strong&gt;Lambda&lt;/strong&gt; es la lambda (parámetro más cuerpo). La lambda identidad se ingresa:&lt;/p&gt; &lt;p&gt;&lt;font face="Consolas"&gt;\x.x&lt;/font&gt;&lt;/p&gt; &lt;p&gt;La versión con múltiples parámetros está soportada:&lt;/p&gt; &lt;p&gt;&lt;font face="Consolas"&gt;\xy.yx&lt;/font&gt;&lt;/p&gt; &lt;p&gt;Como ejemplo, ésta es la implementación de &lt;strong&gt;.Reduce&lt;/strong&gt;&amp;nbsp;para Pair (un pare de expresiones, left and right):&amp;nbsp;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:057a7d15-908a-47c9-b27b-610b940ebae4" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; Expression Reduce()
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.left &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;is&lt;/span&gt;&lt;span style="color:#000000;"&gt; Lambda)
                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; ((Lambda)&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.left).Apply(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.right);

            Expression newLeft &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.left.Reduce();

            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (newLeft &lt;/span&gt;&lt;span style="color:#000000;"&gt;!=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.left)
                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Pair(newLeft, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.right);

            Expression newRight &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.right.Reduce();

            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (newRight &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.right)
                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;;

            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Pair(newLeft, newRight);
        }

&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ejecutando &lt;strong&gt;AjLamnda.Console&lt;/strong&gt; con un parámetro:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;AjLambda.Console Boot.l&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;lee y procesa el archivo auxiliar Boot.l, donde definí algunas funciones predefinidas:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;; True&lt;br /&gt;T = \xy.x&lt;br /&gt;; False&lt;br /&gt;F = \xy.y&lt;br /&gt;; And&lt;br /&gt;AND = \ab.abF&lt;br /&gt;; If Then Else&lt;br /&gt;IFTHENELSE = \x.x&lt;br /&gt;; Natural numbers&lt;br /&gt;0 = \fx.x&lt;br /&gt;1 = \fx.fx&lt;br /&gt;2 = \fx.f(fx)&lt;br /&gt;3 = \fx.f(f(fx))&lt;br /&gt;; Succesor&lt;br /&gt;SUCC = \nfx.f(nfx)&lt;br /&gt;; Add&lt;br /&gt;ADD = \nmfx.nf(mfx)&lt;br /&gt;; Multiply&lt;br /&gt;MULT = \nmf.n(mf)&lt;br /&gt;; Is Zero&lt;br /&gt;ISZERO = \nxy.n(\z.y)x&lt;br /&gt;; Predecessor&lt;br /&gt;PRED = \nfx.n(\gh.h(gf))(\u.x)(\u.u)&lt;br /&gt;; Pair Functions&lt;br /&gt;PAIR = \xyf.fxy&lt;br /&gt;FIRST = \p.pT&lt;br /&gt;SECOND = \p.pF&lt;br /&gt;NIL = \x.T&lt;br /&gt;NULL = \p.p(\xy.F)&lt;br /&gt;; Fixed Point&lt;br /&gt;A = \xy.y(xxy)&lt;br /&gt;Y = A A&lt;br /&gt;; Factorial&lt;br /&gt;FACT = Y (\f.\n.IFTHENELSE (ISZERO n) (1) (MULT n (f (PRED n)))))&lt;/font&gt; 
&lt;p&gt;Podemos preguntar por los nombre predefinidos. Están definidos los primeros números naturales, incluyendo el cero:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajlambdacon01.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Los nombres son palabras que comienzan con una letra mayúscula (o números). Los nombres de variables son letras minúsculas (desde &amp;#39;a&amp;#39; a &amp;#39;z&amp;#39;, una sola letra).&lt;/p&gt;
&lt;p&gt;Como es usual, definí SUCC and PRED (funciones sucesor y predecesor):&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajlambdacon02.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Cada paso de reducción se imprime, hasta que no es posible más reducción.&lt;/p&gt;
&lt;p&gt;Podemos definir nuevas funciones usando Name = &amp;lt;expression&amp;gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajlambdacon03.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Más información sobre Cálculo Lambda en:&lt;/p&gt;
&lt;p&gt;&lt;a title="Lecture Notes on the Lambda Calculus (pdf)" href="http://www.mscs.dal.ca/~selinger/papers/lambdanotes.pdf"&gt;Lecture Notes on the Lambda Calculus (pdf)&lt;/a&gt;&amp;nbsp;(excelente paper para estudiar Lambda Calculus)&lt;/p&gt;
&lt;p&gt;&lt;a title="Peter Selinger- Papers" href="http://www.mscs.dal.ca/~selinger/papers.html"&gt;Peter Selinger- Papers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a title="Lambda calculus - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Lambda_calculus"&gt;Lambda calculus - Wikipedia, the free encyclopedia&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a title="A Tutorial Introduction to the Lambda Calculus" href="http://www.utdallas.edu/~gupta/courses/apl/lambda.pdf"&gt;A Tutorial Introduction to the Lambda Calculus&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://delicious.com/ajlopez/lambda"&gt;http://delicious.com/ajlopez/lambda&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://frmb.org/lambda.html" target="_blank"&gt;Lambda Calculus implementation from Fred&amp;#39;s Page&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com/"&gt;http://www.ajlopez.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1674015" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category></item><item><title>Un ejemplo de Dynamic Expressions</title><link>http://msmvps.com/blogs/lopez/archive/2009/01/31/un-ejemplo-de-dynamic-expressions.aspx</link><pubDate>Sat, 31 Jan 2009 09:01:50 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1667612</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1667612</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/01/31/un-ejemplo-de-dynamic-expressions.aspx#comments</comments><description>&lt;p&gt;El jueves, estaba preparando una presentación para ayer viernes, explicando cálculo lambda, su historia, su aplicación en lenguajes de programación. Al final de la presentación, mostré cómo las lambdas llegaron a .NET: delegados, notación lambda y expresiones lambda.&lt;/p&gt; &lt;p&gt;Haciendo una rápida búsqueda de enlaces para la charla, encontré esta implementación &amp;quot;cool&amp;quot; de un &amp;quot;parser&amp;quot; de expresiones dinámicas, en el ejemplo:&lt;/p&gt; &lt;p&gt;&lt;a title="DynamicLinq.cs" href="http://dblinq2007.googlecode.com/svn/trunk/lib/DynamicLinq.cs"&gt;DynamicLinq.cs&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Ese código menciona el post de Scott Guthrie:&lt;/p&gt; &lt;p&gt;&lt;a title="Dynamic LINQ (Part 1- Using the LINQ Dynamic Query Library)" href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx"&gt;Dynamic LINQ (Part 1- Using the LINQ Dynamic Query Library)&lt;/a&gt;&lt;/p&gt; &lt;p&gt;El código está incluido en el directorio DynamicQuery en:&lt;/p&gt; &lt;p&gt;&lt;a title="C# Dynamic Query Library (included in the -LinqSamples-DynamicQuery directory)" href="http://msdn2.microsoft.com/en-us/vcsharp/bb894665.aspx"&gt;C# Dynamic Query Library (included in the -LinqSamples-DynamicQuery directory)&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Mi idea inicial para la charla era describir una fórmula y compilarala, usando System.Linq.Expressions. Pero la implementación de arriba, tiene una característica notable: en lugar de construir un árbol de expresiones, paso a paso, creando cada nodo, toma un string y los analiza en el momento, convirtiéndolo a una versión compilada.&lt;/p&gt; &lt;p&gt;OK, este truco es usado por muchas implementaciones de query en Linq, pero no conocía que entre el código de ejemplo de Microsoft estuviera este código.&lt;/p&gt; &lt;p&gt;Usando el DynamicLinq.cs, pude crear una aplicación WinForm, donde la fórmula se ingresa y se compila en el momento:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/dynexp01.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Vean que podemos usar clases de .NET. &amp;quot;x&amp;quot; es el parámetro que uso como variable en el cálculo de la fórmula.&lt;/p&gt; &lt;p&gt;Este es el código clave en el archivo Calculator.cs:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:9c327bca-5e16-412b-9ebf-a0739240eb02" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Delegate CompileFormula(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; formula)
        {
            ParameterExpression x &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Expression.Parameter(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color:#000000;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt;), &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;x&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);
            LambdaExpression e &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; DynamicExpression.ParseLambda(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; ParameterExpression[] { x }, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt;, formula);
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; e.Compile();
        }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;El delegado compilado puede ser invocado, proveyendo el valor del parámetro &amp;quot;x&amp;quot;:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:1b63708d-9111-44d5-8f21-8df55a320125" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt;[] Calculate(Delegate formula, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt; from, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt; to, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt; step)
        {
            List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; values &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;();

            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;for&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt; x &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; from; x &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; to; x &lt;/span&gt;&lt;span style="color:#000000;"&gt;+=&lt;/span&gt;&lt;span style="color:#000000;"&gt; step)
                values.Add((&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt;) formula.DynamicInvoke(x));

            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; values.ToArray();
        }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pueden descargar este ejemplo de:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/DynamicExpressionsExample" href="http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/DynamicExpressionsExample"&gt;http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/DynamicExpressionsExample&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Otra implementación de expresiones dinámicas compiladas:&lt;/p&gt;
&lt;p&gt;&lt;a title="To Bind or Not To Bind &amp;ndash; Dynamic Expression Trees &amp;ndash; Part 3 - B# .NET Blog" href="http://community.bartdesmet.net/blogs/bart/archive/2008/08/28/to-bind-or-not-to-bind-dynamic-expression-trees-part-3.aspx"&gt;To Bind or Not To Bind – Dynamic Expression Trees – Part 3 - B# .NET Blog&lt;/a&gt;&lt;br /&gt;&lt;a title="To Bind or Not To Bind &amp;ndash; Dynamic Expression Trees &amp;ndash; Part 2 - B# .NET Blog" href="http://community.bartdesmet.net/blogs/bart/archive/2008/08/27/to-bind-or-not-to-bind-dynamic-expression-trees-part-2.aspx"&gt;To Bind or Not To Bind – Dynamic Expression Trees – Part 2 - B# .NET Blog&lt;/a&gt;&lt;br /&gt;&lt;a title="To Bind or Not To Bind &amp;ndash; Dynamic Expression Trees &amp;ndash; Part 1 - B# .NET Blog" href="http://community.bartdesmet.net/blogs/bart/archive/2008/08/26/to-bind-or-not-to-bind-dynamic-expression-trees-part-1.aspx"&gt;To Bind or Not To Bind – Dynamic Expression Trees – Part 1 - B# .NET Blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Algunas ideas a explorar:&lt;/p&gt;
&lt;p&gt;- Extender el ejemplo a tres dimensiones (podría usar un ejemplo que viene en F# con DirectX como base)&lt;/p&gt;
&lt;p&gt;- Enviar una fórmula como texto, para ser procesada en una aplicación distribuida, grilla, o cluster de HPC. Por ejemplo, la fórmula del fractal&amp;nbsp;a calcular en forma distribuida.&lt;/p&gt;
&lt;p&gt;- Code kata escribiendo mi propio&amp;nbsp;.Parse y .Compile para alguno de mis lenguajes de scripting&lt;/p&gt;
&lt;p&gt;Si necesitan más poder, el próximo nivel de lenguajes dinámicos y su compilación a .NET, ese el namespace&amp;nbsp; Microsoft.Scripting dentro del código fuente de IronPython:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://www.codeplex.com/IronPython/SourceControl" href="http://www.codeplex.com/IronPython/SourceControl"&gt;http://www.codeplex.com/IronPython/SourceControl&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Introducciones a IronPython y la iniciativa DLR:&lt;/p&gt;
&lt;p&gt;&lt;a title="CLR Inside Out- IronPython and the Dynamic Language Runtime" href="http://msdn.microsoft.com/en-us/magazine/cc163344.aspx"&gt;CLR Inside Out- IronPython and the Dynamic Language Runtime&lt;/a&gt;&lt;br /&gt;&lt;a title="CLR Inside Out- Dynamic Languages and Silverlight" href="http://msdn.microsoft.com/en-us/magazine/cc163284.aspx"&gt;CLR Inside Out- Dynamic Languages and Silverlight&lt;/a&gt;&lt;br /&gt;&lt;a title="InfoQ- Microsoft Surpasses Java&amp;#39;s Dynamic Language Support-" href="http://www.infoq.com/news/2007/05/java-dlr"&gt;InfoQ- Microsoft Surpasses Java&amp;#39;s Dynamic Language Support-&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/es-ar/magazine/cc300810(en-us).aspx" target="_blank"&gt;CLR Inside Out - IronPython&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enlaces relacionados sobre lambda, Dynamic Language Runtime, y lenguajes dinámicas en general:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://delicious.com/ajlopez/lambda"&gt;http://delicious.com/ajlopez/lambda&lt;/a&gt;&lt;br /&gt;&lt;a href="http://delicious.com/ajlopez/dlr"&gt;http://delicious.com/ajlopez/dlr&lt;/a&gt;&lt;br /&gt;&lt;a href="http://delicious.com/ajlopez/dynamiclanguages"&gt;http://delicious.com/ajlopez/dynamiclanguages&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1667612" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category></item><item><title>AjGa: una librería de algoritmos genéticos</title><link>http://msmvps.com/blogs/lopez/archive/2009/01/28/ajga-una-librer-237-a-de-algoritmos-gen-233-ticos.aspx</link><pubDate>Wed, 28 Jan 2009 07:33:03 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1666502</guid><dc:creator>lopez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1666502</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/01/28/ajga-una-librer-237-a-de-algoritmos-gen-233-ticos.aspx#comments</comments><description>&lt;p&gt;Estuve codificando una librería de algoritmos genéticos, usando C#. El código está en mi proyecto &lt;a href="http://code.google.com/p/ajcodekatas/" target="_blank"&gt;AjCodeKatas en Google Code&lt;/a&gt;&amp;nbsp;dentro de:&lt;/p&gt; &lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjGa" href="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjGa"&gt;http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjGa&lt;/a&gt;&lt;/p&gt; &lt;p&gt;El proyecto principal es AjGa (con AjGa.Tests para testing):&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgasln.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Las principales interfaces son:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgaint.png" alt="" /&gt;&lt;/p&gt; &lt;p&gt;Uso generics, con dos tipos genéricos: G, que es el tipo de implementación de un gen, y V como el tipo al que se evalúa un genoma (por ejemplo, int, double). Con ese valor se catalogan los genomas.&lt;/p&gt; &lt;p&gt;IPopulation es una colección de genomas.&lt;/p&gt; &lt;p&gt;IGenome &amp;nbsp;es una colección&amp;nbsp;de genes, que&amp;nbsp;es evaluado a un valor de tipo V.&lt;/p&gt; &lt;p&gt;IEvaluator está a cargo de evaluar un genoma.&lt;/p&gt; &lt;p&gt;La implementación de IEvolution ejecuta generaciones sobre una población, que va cambiando, usando mutadores, operadores de cruzamiento, para irla modificando después de cada ejecución.&lt;/p&gt; &lt;p&gt;Hay interfaces para generar un genoma, mutar uno existente o hacer cruzamiento de dos genomas.&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgacd.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Para probar estas ideas, implementé un proyecto con gen, genoma, y operadores, que ataca el clásico problema del Travelling Salesman Problem, el vendedor que tiene que visitar una serie de ciudades, minimazando la distancia a recorrrer:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgatspprj.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;En este ejemplo, el evaluador tiene una lista de posiciones de ciudades a visitar:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:d2ccf8d5-26f7-4c4f-9980-20d15c5489ec" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Evaluator : IEvaluator&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Position&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; positions;

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Evaluator(List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Position&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; positions)
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.positions &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; positions;
        }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;El tipo de gen acá es int, y cada valor de genoma se expresa como un int. El genoma mantiene una lista de enteros, que representan el&amp;nbsp;número ordinal de las ciudades a visitar:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:2ba01ca7-37cc-404b-9b73-a7bb089f9ef0" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; AjGa;

    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Genome : BaseGenome&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    {        
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Genome(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; size)
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;for&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; k &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;; k &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; size; k&lt;/span&gt;&lt;span style="color:#000000;"&gt;++&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
            {
                AddGene(k);
            }
        }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Esto es, cada gen es un int, y un genoma con genes 2, 0, 1, representa un viaje que visita la tercera ciudad, pasa por la primera, y termina en la segunda.&lt;/p&gt;
&lt;p&gt;Podemos ejecutar el proyecto WinForm, para probar esta implementación:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgatsp1.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;En la ejecución de arriba, la distribución de ciudades es al azar. Las ciudades pueden ser distribuidas en una grilla:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgatsp2.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;De esta forma, podemos probar la eficiencia del algoritmo para encontrar un solución óptima, que en el caso de disponer las ciudades en grilla, se conoce de antemano.&lt;/p&gt;
&lt;p&gt;Si queremos implementar un nuevo proyecto GA, tenemos que:&lt;/p&gt;
&lt;p&gt;- Definir el tipo que tendrán los genes&lt;/p&gt;
&lt;p&gt;- Definir el tipo valor a usar&lt;/p&gt;
&lt;p&gt;- Escribir operadores (creadores, mutadores, cruzadores) de genomas&lt;/p&gt;
&lt;p&gt;Los tests que tengo están en verde:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgatests.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Buen Code coverage:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgacc.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;En 4 horas tuve la primera versión, gasté 3 horas explorando TSP, y cerca de 8 horas preparando y &amp;quot;tuneando&amp;quot; la aplicación WinForm.&lt;/p&gt;
&lt;p&gt;Como de costumbre, ¡me divertí escribiendo este ejemplo!&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1666502" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Inteligencia+Artificial/default.aspx">Inteligencia Artificial</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category></item><item><title>Clean Code Talks -- Herencia, Polimorfismo y Tests</title><link>http://msmvps.com/blogs/lopez/archive/2009/01/13/clean-code-talks-herencia-polimorfismo-y-tests.aspx</link><pubDate>Tue, 13 Jan 2009 09:15:54 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1661311</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1661311</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/01/13/clean-code-talks-herencia-polimorfismo-y-tests.aspx#comments</comments><description>&lt;p&gt;Son un usuario fanático de &lt;a href="http://twitter.com" target="_blank"&gt;Twitter&lt;/a&gt;. Una cuenta a la que sigo es &lt;a href="http://twitter.com/delicious_prog" target="_blank"&gt;@delicious_prog&lt;/a&gt;, que envía varios mensajes por día, relacionados con programación, desarrollo de software en general. En uno de esos tweets, encontré el post&lt;/p&gt; &lt;p&gt;&lt;a title="The Clean Code Talks -- Inheritance, Polymorphism, &amp;amp; Testing" href="http://danielwildt.blogspot.com/2008/12/clean-code-talks-inheritance.html"&gt;The Clean Code Talks -- Inheritance, Polymorphism, &amp;amp; Testing&lt;/a&gt;&lt;/p&gt; &lt;p&gt;de &lt;a href="http://danielwildt.blogspot.com/" target="_blank"&gt;Daniel Wild&lt;/a&gt;, donde incluye el vidio de una&amp;nbsp; Google Talk:&lt;/p&gt; &lt;p&gt;(Please visit the site to view this media)&lt;/p&gt; &lt;p&gt;de &lt;a title="Misko Hevery" href="http://misko.hevery.com/"&gt;Misko Hevery&lt;/a&gt;&amp;nbsp;en &lt;a title="Google Tech Talks" href="http://www.youtube.com/user/googletechtalks"&gt;Google Tech Talks&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Es claro e interesante. Es una charla explicando los usos del polimorfismo, y también, las formas de realizar test sobre métodos polimórficos. Me gusta encontrara en este vido varios argumentos similares a los que uso en mis charlas de desarrollo. Hace unos días, estuve usando polimorfirsmo en mi intérprete AjCat (un intérprete del lenguaje cat que me hizo conocer el bueno de &lt;a href="http://twitter.com/rodolfof" target="_blank"&gt;@rodolfof&lt;/a&gt;):&lt;/p&gt; &lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjCat" href="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjCat"&gt;http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjCat&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Esta es mi implmentación de Integer Binary Operation:&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:cdb4759a-0b2e-4dd0-baba-262fca4716a3" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;abstract&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntegerBinaryOperation : Expression
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;abstract&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; Apply(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; op1, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; op2);

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Evaluate(Machine machine)
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; op2 &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;) machine.Pop();
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; op1 &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;) machine.Pop();

            machine.Push(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.Apply(op1, op2));
        }
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Las operaciones Add y Subtract sobreescriben el método Apply:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:b267ea20-7c62-4901-aa2d-613a963a5602" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntegerAddOperation : IntegerBinaryOperation
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntegerAddOperation instance &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntegerAddOperation();

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntegerAddOperation()
        {
        }

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntegerAddOperation Instance
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            {
                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; instance;
            }
        }

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; Apply(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; op1, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; op2)
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; op1 &lt;/span&gt;&lt;span style="color:#000000;"&gt;+&lt;/span&gt;&lt;span style="color:#000000;"&gt; op2;
        }

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; ToString()
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;add_int&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
        }
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:5019eb84-44e9-4e8c-b22c-d7d28428c75e" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntegerSubtractOperation : IntegerBinaryOperation
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntegerSubtractOperation instance &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntegerSubtractOperation();

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntegerSubtractOperation()
        {
        }

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; IntegerSubtractOperation Instance
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            {
                &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; instance;
            }
        }

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; Apply(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; op1, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; op2)
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; op1 &lt;/span&gt;&lt;span style="color:#000000;"&gt;-&lt;/span&gt;&lt;span style="color:#000000;"&gt; op2;
        }

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; ToString()
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;sub_int&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
        }
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Es muy similar al ejemplo presentado en el video. Estuve algo más perezoso en mi implementación de operadores en&amp;nbsp; AjPython (otro intérprete, de nuevo en&amp;nbsp;C#, trabajo en progreso):&lt;/p&gt;
&lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjPython" href="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjPython"&gt;http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjPython&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:c1ceebe0-dcbd-4655-b75c-cab5830acc73" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; BinaryOperatorExpression : BinaryExpression
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; Operator @operator;

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; BinaryOperatorBLOCKED EXPRESSION;
        }
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pero confío en refactorearlo, tengo espaldas para hacerlo, gracias una buena base de test ya escritos.&lt;/p&gt;
&lt;p&gt;Es bueno encontrar este tipo de material, como esta charla, la recomiendo, gracias a&amp;nbsp; @delicious_prog y a Daniel Wild!&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1661311" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category></item><item><title>Fractales usando MPI.NET y HPC</title><link>http://msmvps.com/blogs/lopez/archive/2008/12/28/fractales-usando-mpi-net-y-hpc.aspx</link><pubDate>Sun, 28 Dec 2008 18:50:34 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1657908</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1657908</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2008/12/28/fractales-usando-mpi-net-y-hpc.aspx#comments</comments><description>&lt;p&gt;Actualicé&amp;nbsp;&lt;a href="http://msmvps.com/blogs/lopez/archive/2008/12/19/fractal-revisitado.aspx" target="_blank"&gt;mi ejemplo de fractal&lt;/a&gt; y ahora soporta&amp;nbsp;MPI.NET (Message Passing Interface with .NET) y tasks paramétricas en Windows HPC Server 2008. El ejemplo puede ser bajado desde mi proyecto Google code&amp;nbsp;&lt;a href="http://code.google.com/p/ajcodekatas"&gt;ajcodekatas&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;a href="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/FractalExample"&gt;http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/FractalExample&lt;/a&gt;  &lt;p&gt;Hay dos soluciones. Esta es la &lt;strong&gt;Fractal.sln&lt;/strong&gt;:  &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/codekatafractalsln2.png" alt="" /&gt;  &lt;p&gt;El proyecto &lt;strong&gt;Fractal.Console&lt;/strong&gt; es una aplicación de consola que toma parámetros de la línea de comando. Los usa para generar un sector del fractal, al que serializa binariamente en un archivo:  &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:9f9a5df7-0ec4-4ce1-b593-b14e14d4066f" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Main(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt;[] args)
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (args[&lt;/span&gt;&lt;span style="color:#000000;"&gt;4&lt;/span&gt;&lt;span style="color:#000000;"&gt;].Equals(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;*&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;))
                args[&lt;/span&gt;&lt;span style="color:#000000;"&gt;4&lt;/span&gt;&lt;span style="color:#000000;"&gt;] &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;;

            SectorInfo sectorinfo &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SectorInfo()
            {
                RealMinimum &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Convert.ToDouble(args[&lt;/span&gt;&lt;span style="color:#000000;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;]),
                ImgMinimum &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Convert.ToDouble(args[&lt;/span&gt;&lt;span style="color:#000000;"&gt;1&lt;/span&gt;&lt;span style="color:#000000;"&gt;]),
                Delta &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Convert.ToDouble(args[&lt;/span&gt;&lt;span style="color:#000000;"&gt;2&lt;/span&gt;&lt;span style="color:#000000;"&gt;]),
                FromX &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Convert.ToInt32(args[&lt;/span&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;span style="color:#000000;"&gt;]),
                FromY &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Convert.ToInt32(args[&lt;/span&gt;&lt;span style="color:#000000;"&gt;4&lt;/span&gt;&lt;span style="color:#000000;"&gt;]),
                Width &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Convert.ToInt32(args[&lt;/span&gt;&lt;span style="color:#000000;"&gt;5&lt;/span&gt;&lt;span style="color:#000000;"&gt;]),
                Height &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Convert.ToInt32(args[&lt;/span&gt;&lt;span style="color:#000000;"&gt;6&lt;/span&gt;&lt;span style="color:#000000;"&gt;]),
                MaxIterations &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Convert.ToInt32(args[&lt;/span&gt;&lt;span style="color:#000000;"&gt;7&lt;/span&gt;&lt;span style="color:#000000;"&gt;]),
                MaxValue &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; Convert.ToInt32(args[&lt;/span&gt;&lt;span style="color:#000000;"&gt;8&lt;/span&gt;&lt;span style="color:#000000;"&gt;])
            };

            Calculator calculator &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Calculator();

            Sector sector &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; calculator.CalculateSector(sectorinfo);

            SectorSerializer serializer &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SectorSerializer();

            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; filename &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt;.Format(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;{0}-{1}-{2}-{3}-{4}.bin&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, args[&lt;/span&gt;&lt;span style="color:#000000;"&gt;9&lt;/span&gt;&lt;span style="color:#000000;"&gt;], sectorinfo.FromX, sectorinfo.FromY, sectorinfo.Width, sectorinfo.Height);

            serializer.Serialize(sector, filename);
        }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Pueden ejecutar el proyecto en modo DebugYou can run the project in Debug mode, con parámetros:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/codekatafractalpar.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Lancen el nuevo proyecto &lt;strong&gt;Fractal.GUIFiles&lt;/strong&gt;. Es una aplicación WinForm, como la que presenté en mi anterior posts, pero con un nuevo botón Read a la derecha:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="http://www.todocontenidos.com/images/articles/codekatafractalfiles.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Con ese botón, pueden seleccionar uno más archivos de sector, como el que generó &lt;strong&gt;Fractal.Console&lt;/strong&gt; en su directorio bin\debug:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/codekatafractalopen.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Este es el resultado:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/codekatafractalsector.png" alt="" /&gt; &lt;/p&gt;
&lt;h3&gt;Creando sectores con HPC&lt;/h3&gt;
&lt;p&gt;La aplicación de consola puede ser usada en un cluster. Supongamos que la aplicación está instalada en el directorio c:\FractalConsole en cada nodo del cluster. Supongamos que el nombre de la máquina head del cluster es HEAD-NODE, y que ahí hay un directorio compartido llamado \shared, que puede ser accedido desde cada nodo. Entones, podemos lanzar un job paramétrico:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;job submit /parametric:0-500:100 c:\FractalConsole\Fractal.Console.exe 0.3 0.3 0.01 0 * 1000 100 2000 4 \\HEAD-NODE\shared\sector&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Este comando envía un trabajo al cluster, pero con un parámetro variable. El asterisco en la lista de parámetros será reemplazado por los valores 0,100,200,300,400 y 500 (en este caso, es la coordinada Y de la esquina superior izquierda de un sector). Cada ejecución producirá un archivo con un sector serializado en el directorio compardio, que podremos leer&amp;nbsp;y mostrar usando la aplicación &lt;strong&gt;Fractal.GUIFiles&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Usando MPI.NET&lt;/h3&gt;
&lt;p&gt;Hay una segunda solución &lt;strong&gt;Fractal.MPI&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/codekatafractalsln3.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Este código usa&amp;nbsp;MPI&amp;nbsp;(Message Passing Interface).&amp;nbsp;El rank 0 recibe los datos de un sector, y&amp;nbsp;lo parte en subsectores, que son enviados a todos los ranks (instancias) de la aplicación. Cada instancia genera un archivo, con la serialización de&amp;nbsp;un subsector del sector original.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Para compilar y ejecutar este ejemplo hay que instalar el HPC Pack que se baja de: &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=12887da1-9410-4a59-b903-693116bfd30e&amp;amp;displaylang=en"&gt;HPC Pack 2008 SDK download&lt;/a&gt; 
&lt;p&gt;e instalar el &lt;a href="http://www.osl.iu.edu/research/mpi.net/software/"&gt;MPI.NET Software&lt;/a&gt; 
&lt;p&gt;(Yo instalé&amp;nbsp;&lt;a href="http://www.osl.iu.edu/research/mpi.net/files/1.0.0/MPI.NET%20SDK.msi"&gt;MPI.NET SDK.msi&lt;/a&gt;&amp;nbsp;pero también bajé y expandí &lt;a href="http://www.osl.iu.edu/research/mpi.net/files/1.0.0/MPI.NET-1.0.0.zip"&gt;MPI.NET-1.0.0.zip&lt;/a&gt;: tiene mejores ejemplos, con soluciones completas para Visual Studio) 
&lt;p&gt;(Nota: si quieren ejecutar el ejemplo bajo XP Pro, deben bajarse NO el HPC Pack, sino la anterior versión:&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=d8462378-2f68-409d-9cb3-02312bc23bfd&amp;amp;displaylang=en" target="_blank"&gt;Microsoft Compute Cluster Pack SDK&lt;/a&gt; 
&lt;p&gt;El nuevo SDK tiene un problema con XP. Más información en: 
&lt;p&gt;&lt;a title="http://social.microsoft.com/Forums/en-US/windowshpcdevs/thread/19deb181-15c2-40be-bb5e-2d4604b984a4" href="http://social.microsoft.com/Forums/en-US/windowshpcdevs/thread/19deb181-15c2-40be-bb5e-2d4604b984a4"&gt;http://social.microsoft.com/Forums/en-US/windowshpcdevs/thread/19deb181-15c2-40be-bb5e-2d4604b984a4&lt;/a&gt;&lt;br /&gt;&lt;a title="http://www.pluralsight.com/community/blogs/drjoe/archive/2008/10/10/32-bit-sdk-for-hpc-server-2008-fails-quot-the-procedure-entry-point-getprocessidofthread-could-not-be-located-quot.aspx" href="http://www.pluralsight.com/community/blogs/drjoe/archive/2008/10/10/32-bit-sdk-for-hpc-server-2008-fails-quot-the-procedure-entry-point-getprocessidofthread-could-not-be-located-quot.aspx"&gt;http://www.pluralsight.com/community/blogs/drjoe/archive/2008/10/10/32-bit-sdk-for-hpc-server-2008-fails-quot-the-procedure-entry-point-getprocessidofthread-could-not-be-located-quot.aspx&lt;/a&gt;&lt;br /&gt;) 
&lt;p&gt;Podemos ejecutar el programa usando el utilitario mpiexec, que lanza varias instancias de un mismo programa, conectados como ranks de MPI:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;mpiexec -n 10 Fractal.Mpi.Exe 0 0 0.01 0 0 500 1000 2000 4 sector&lt;/font&gt; 
&lt;p&gt;El sector será producido entonces por 10 instancias, en este caso: 
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/codekatafractalmpi.png" alt="" /&gt; 
&lt;p&gt;que podemos leer y mostrar usando &lt;strong&gt;Fractal.GUIFiles&lt;/strong&gt;. 
&lt;p&gt;Podemos ejecutar el anterior comando en un HPC cluster, usando: 
&lt;p&gt;&lt;font face="Consolas"&gt;job submit /numnodes=10 mpiexec&amp;nbsp;c:\FractalMpi\Fractal.Mpi.Exe 0 0 0.01 0 0 500 1000 2000 4 \\HEAD-NODE\shared\sector&lt;/font&gt; 
&lt;p&gt;(asumiendo que hemos copiado la aplicación en cada nodo, dentro del directorio c:\FractalMpi de cada nodo) 
&lt;p&gt;Para un más completo ejemplo, ver: 
&lt;p&gt;&lt;a href="http://www.pluralsight.com/community/blogs/drjoe/archive/2008/08/18/learning-parallel-programming-from-shared-memory-multi-threading-to-distributed-memory-multi-processing.aspx"&gt;Learning Parallel Programming — from shared-memory multi-threading to distributed-memory multi-processing&lt;/a&gt; 
&lt;p&gt;Nos leemos!
&lt;p&gt;Angel “Java” Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter/ajlopez"&gt;http://twitter/ajlopez&lt;/a&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1657908" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/High+Performance+Computing/default.aspx">High Performance Computing</category></item><item><title>Fractal revisitado</title><link>http://msmvps.com/blogs/lopez/archive/2008/12/19/fractal-revisitado.aspx</link><pubDate>Fri, 19 Dec 2008 13:20:23 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1657239</guid><dc:creator>lopez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1657239</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2008/12/19/fractal-revisitado.aspx#comments</comments><description>&lt;p&gt;Este año, había escrito una demostración de generación de fractal, usando DSS/CCR, ver:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ajlopez.wordpress.com/2008/06/22/distributed-agents-and-fractals-using-dssvpl/" target="_blank"&gt;Distributed Agents and Fractals using DSS/VPL&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2008/06/20/agentes-distribuidos-usando-dss-vpl.aspx"&gt;Agentes Distribuidos usando DSS/VPL&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Ahora, estoy explorando pasar el ejemplo a ejecución en paralelo, usando, entre otras tecnologías, Task Parallel Library, threads, o MPI (Message Passing Interface). Antes de pasar a programar esas nuevas versiones, añadí a mi proyecto Google code &lt;a href="http://code.google.com/p/ajcodekatas" target="_blank"&gt;ajcodekatas&lt;/a&gt;, una aplicación base, un WinForm que dibuja un fractal, usando un solo thread, el mismo del proceso de la GUI:&lt;/p&gt; &lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/FractalExample" href="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/FractalExample"&gt;http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/FractalExample&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/codekatafractalsln.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Tiene una librería de clases, con las clases principales, y un proyecto WinForm, que usa un objeto &lt;strong&gt;Calculator&lt;/strong&gt; para calcular un &lt;strong&gt;Sector&lt;/strong&gt; del fractal. Un fragmento de la invocación:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:9b26636e-9c37-492e-9744-994b43a9f3a6" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; Calculate()
        {
            Bitmap bitmap &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Bitmap(pcbFractal.Width, pcbFractal.Height);
            pcbFractal.Image &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; bitmap;
            pcbFractal.Refresh();

            realWidth &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; realDelta &lt;/span&gt;&lt;span style="color:#000000;"&gt;*&lt;/span&gt;&lt;span style="color:#000000;"&gt; pcbFractal.Width;
            imgHeight &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; imgDelta &lt;/span&gt;&lt;span style="color:#000000;"&gt;*&lt;/span&gt;&lt;span style="color:#000000;"&gt; pcbFractal.Height;

            realMin &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; realCenter &lt;/span&gt;&lt;span style="color:#000000;"&gt;-&lt;/span&gt;&lt;span style="color:#000000;"&gt; realWidth &lt;/span&gt;&lt;span style="color:#000000;"&gt;/&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;2&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
            imgMin &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; imgCenter &lt;/span&gt;&lt;span style="color:#000000;"&gt;-&lt;/span&gt;&lt;span style="color:#000000;"&gt; imgHeight &lt;/span&gt;&lt;span style="color:#000000;"&gt;/&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;2&lt;/span&gt;&lt;span style="color:#000000;"&gt;;

            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; width &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; pcbFractal.Width;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; height &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; pcbFractal.Height;

            SectorInfo sectorinfo &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SectorInfo()
            {
                FromX &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
                FromY &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;,
                Width &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; width,
                Height &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; height,
                RealMinimum &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; realMin,
                ImgMinimum &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; imgMin,
                Delta &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; realDelta,
                MaxIterations &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; colors.Length,
                MaxValue &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;4&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            };

            Calculator calculator &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Calculator();
            Sector sector &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; calculator.CalculateSector(sectorinfo);
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.DrawValues(sector.FromX, sector.FromY, sector.Width, sector.Height, sector.Values);
        }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ejecutando el proyecto&amp;nbsp;&lt;strong&gt;Fractal.GUI&lt;/strong&gt;, y haciendo click en el botón de Calculate, obtenemos:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/codekatafractalimg1.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Podemos arrastrar el mouse, seleccionando una zona. Al soltarlo, una nueva imagen es generada. Podemos cambiar los colores, que son generados al azar:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/codekatafractalimg2.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/codekatafractalimg3.png" alt="" /&gt; &lt;/p&gt;
&lt;h3&gt;Próximos pasos&lt;/h3&gt;
&lt;p&gt;Quiero añadir en las nuevas versiones:&lt;/p&gt;
&lt;p&gt;- Una versión multithread&lt;/p&gt;
&lt;p&gt;- Una versión en paralelo usando &lt;a href="http://blogs.msdn.com/pfxteam/archive/tags/Task+Parallel+Library/default.aspx" target="_blank"&gt;Task Parallel Library&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- Una versión distribuida (&lt;a href="http://ajlopez.wordpress.com/2008/12/07/first-steps-with-mpinet-programming/" target="_blank"&gt;MPI.NET&lt;/a&gt;? &lt;a href="http://ajlopez.wordpress.com/category/ajmessages/" target="_blank"&gt;AjMessages&lt;/a&gt;?)&lt;/p&gt;
&lt;p&gt;Parte de la aplicación la vamos a mostrar en el webcast de hoy:&lt;/p&gt;
&lt;p&gt;&lt;a title="Webcast de desarrollo con Windows HPC Server 2008" href="http://msmvps.com/blogs/lopez/archive/2008/12/18/webcast-de-desarrollo-con-windows-hpc-server-2008.aspx"&gt;Webcast de desarrollo con Windows HPC Server 2008&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si son impacientes, puede ver este excelente tutorial, que implementa una aplicación fractal usando HPC 2008, y también con las tecnologías que mencioné arriba, está listo para descargar con código desde:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.pluralsight.com/community/blogs/drjoe/archive/2008/08/18/learning-parallel-programming-from-shared-memory-multi-threading-to-distributed-memory-multi-processing.aspx"&gt;Learning Parallel Programming — from shared-memory multi-threading to distributed-memory multi-processing&lt;/a&gt; 
&lt;p&gt;Sugerencias, comentarios, bienvenidos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com/en"&gt;http://www.ajlopez.com/en&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1657239" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category></item><item><title>Jugando con programas evolutivos</title><link>http://msmvps.com/blogs/lopez/archive/2008/12/16/jugando-con-programas-evolutivos.aspx</link><pubDate>Tue, 16 Dec 2008 08:59:47 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1656840</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1656840</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2008/12/16/jugando-con-programas-evolutivos.aspx#comments</comments><description>&lt;p&gt;El fin de semanas, estuve escribiendo un ejercicio casi tipo &lt;a href="http://codekata.pragprog.com/2007/01/code_kata_backg.html" target="_blank"&gt;codekata&lt;/a&gt;. Me gusta explorar la idea de programas evolutivos (como agentes con programas incorporados que van evolucionando en ambientes simulados), así que puse manos a la obra, y creé una solución dedicada a experimentar con una ejemplo de prueba de concepto. Está escrito en C#, usando VS 2008, usando el soporte de test de la herramienta. He publicado el código dentro de mi Google code project &lt;a href="http://code.google.com/p/ajcodekatas"&gt;ajcodekatas&lt;/a&gt; en:&lt;/p&gt; &lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/EvolveExample" href="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/EvolveExample"&gt;http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/EvolveExample&lt;/a&gt;&lt;/p&gt; &lt;p&gt;La solución es &lt;strong&gt;EvolveExample&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/evolveexamplesln.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;(Si no tienen el soporte de test de VS, pueden remover el proyecto &lt;strong&gt;Evolve.Test&lt;/strong&gt;).&lt;/p&gt; &lt;p&gt;Las clases principales residen en el proyecto de librería de clases &lt;strong&gt;Evolve&lt;/strong&gt; :&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/evolveexamplecld.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Animal&lt;/strong&gt; representa&amp;nbsp;un agente. Tiene una lista de&amp;nbsp;Instructions, que son generadas al azar. El animal habita un campo con&amp;nbsp;comida.&amp;nbsp;Su programa tiene instrucciones como Eat, Move East, North, West, South, o Predate (tomar energía/comida de otro animal que esté en la misma celda de la grilla). Cada instrucción tiene un costo: un punto de energía. Eat es una instrucción que toma 10 puntos de energía o menos, tomando comida de la celda actual. Predate toma 100 puntos de energía o menos, restándoselo a otro animal que esté en la misma celda.&lt;/p&gt; &lt;p&gt;Para ver el programa en acción, lanzar el proyecto winform &lt;strong&gt;Evolve.GUI&lt;/strong&gt;, seleccionar la opción &lt;strong&gt;Evolve -&amp;gt; Run&lt;/strong&gt;. Veremos:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/evolveexamplegui.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;El campo es una grilla (en este ejemplo, de 20x20). Cada celda tiene un nivel de comida (verde está llena, negro es vacía). A la derecha, una lista muestra los mejores animales y sus programas. Los animales son rankeados de acuerdo a su nivel de energía al final de cada ronda de simulación. El programa continúa con más simulaciones, usando nuevos campos. En cada nueva simulación, la población es ordenada por energía descendente, y los mejores son incluidos en la nueva simulación,&amp;nbsp;los lugares vacantes son ocupados por mutaciones de esos mejores, y algunos&amp;nbsp;animales son inyectados con programas aleatorios.&lt;/p&gt; &lt;p&gt;Durante una simulación, aparece información sobre el nivel de comida y el animal que mejor se desempaña, al pie de la ventana.&lt;/p&gt; &lt;p&gt;Con las opciones de menú &lt;strong&gt;Food&lt;/strong&gt; y &lt;strong&gt;Population&lt;/strong&gt; podemos establecer el nivel de comida y el número de animales, a usar al comienzo de cada simulación. Estos valores se usan recién la próxima vez que elijamos &lt;strong&gt;Evolve -&amp;gt; Run&lt;/strong&gt;. La opción &lt;strong&gt;Evolve -&amp;gt; Stop&amp;nbsp;&lt;/strong&gt;puede ser usado para terminar una serie de simulaciones.&lt;/p&gt; &lt;h3&gt;Próximos pasos&lt;/h3&gt; &lt;p&gt;Este es un primer ejemplo, una prueba de concepto que sirva de base. Tengo algunas ideas, para explorar en futuras versiones:&lt;/p&gt; &lt;p&gt;- Tener un conjunto de instrucciones más interesantes, con condicionales, y que sea sensible al ambiente. Me gustaría añadir instrucciones como &amp;quot;Si hay comida en tal dirección, ir hacia allí&amp;quot;. En vez de un programa lineal, podría armar un árbol de instrucciones, algo como un programa Lisp.&lt;/p&gt; &lt;p&gt;- Los valores de ejecución (tamaño del campo, nivel de comida, energía inicial para cada animal), deberían poder establecerse por un formulario, y leer y grabarse de archivos XML.&lt;/p&gt; &lt;p&gt;- Serializar los resultados y poblaciones en archivos XML&lt;/p&gt; &lt;p&gt;- Evolución en un cluster. Podría usar AjMessages, AjAgents, o MPI sobre unc luster HPC, para simular evolución en una grilla o cluster de máquinas.&lt;/p&gt; &lt;p&gt;Como es habitual, ¡me divertí escribiendo este código!&lt;/p&gt; &lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;br /&gt;&lt;a href="http://delicious.com/ajlopez"&gt;http://delicious.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1656840" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Inteligencia+Artificial/default.aspx">Inteligencia Artificial</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category></item><item><title>Máquinas de Estado en C# 3.0 usando AjGenesis</title><link>http://msmvps.com/blogs/lopez/archive/2008/10/21/m-225-quinas-de-estado-en-c-3-0-usando-ajgenesis.aspx</link><pubDate>Tue, 21 Oct 2008 09:39:39 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1651489</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1651489</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2008/10/21/m-225-quinas-de-estado-en-c-3-0-usando-ajgenesis.aspx#comments</comments><description>&lt;p&gt;Recientemente encontré el trabajo de &lt;a title="Andrew Matthews" href="http://aabs.wordpress.com/"&gt;Andrew Matthews&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;a title="Permanent Link to State Machines in C# 3.0 using T4 Templates" href="http://aabs.wordpress.com/2008/06/26/state-machines-in-c-30-using-t4-templates/"&gt;Permanent Link to State Machines in C# 3.0 using T4 Templates&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Tomé el ejemplo y lo reimplementé usando mi proyecto de generación de código &lt;a href="http://www.ajlopez.com/ajgenesis" target="_blank"&gt;AjGenesis&lt;/a&gt;. Para correr este ejemplo, tenemos que bajar la última versión publicada 0.5 desde &lt;a href="http://www.codeplex.com/ajgenesis"&gt;la página del proyecto en Codeplex&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;(más información sobre el proyecto, ejemplos, explicación del funcionamiento en &lt;a href="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx" target="_blank"&gt;mis anteriores posts&lt;/a&gt;).&lt;/p&gt; &lt;p&gt;Pueden bajar &lt;a href="http://www.ajlopez.com/downloads/AjGenesisStateMachine.zip" target="_blank"&gt;el código de este ejemplo&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;El modelo que usé es el mismo del post original de Andrew:&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:31d7985f-401f-4174-b268-899b991b3aa3" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;width:493px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;StateModels&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;StateModel &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;ID&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;My&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; start&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon1&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;States&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;State &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;ID&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon1&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon1&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;State &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;ID&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon2&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon2&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;State &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;ID&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon3&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon3&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;States&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Inputs&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Input &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;ID&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;diplomaticIncident&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;diplomaticIncident&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Input &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;ID&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;assassination&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;assassination&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Input &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;ID&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;coup&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;coup&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Inputs&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Transitions&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Transition &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;from&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon1&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; to&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon2&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; on&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;diplomaticIncident&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Transition &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;from&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon2&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; to&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon3&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; on&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;assassination&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Transition &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;from&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon3&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; to&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;defcon1&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; on&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;coup&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Transitions&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;StateModel&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;StateModels&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;(Andrew escribió que ha sido influido un poco por la serie de TV 24, al elegir los estados del ejemplo... ;-)&lt;/p&gt;
&lt;p&gt;Modifiqué la solución original:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgenesisstates.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Ahora, hay un archivo &lt;strong&gt;Model.xml&lt;/strong&gt; que contiene el modelo de arriba. El archivo &lt;strong&gt;MyStateModel.cs&lt;/strong&gt;&amp;nbsp;es automáticamente generado desde el modelo. Cambié la solución para tener un evento de Pre-Build en el proyecto &lt;strong&gt;TestHarness&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;$(ProjectDir)..\VsMakeStates.cmd&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;El archivo .cmd contiene:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;cd ..\..\..&lt;br /&gt;c:\ajlopez\ProyectosNet2\AjGenesis-0.5\bin\AjGenesis.Console TestHarness\Model.xml GenStates.ajg &lt;/font&gt;
&lt;p&gt;(&lt;strong&gt;TENEMOS&lt;/strong&gt; que cambiar la segunda línea para apuntar al directorio binario de AjGenesis 0.5)&lt;/p&gt;
&lt;p&gt;Con este comando, &lt;strong&gt;AjGenesis.Console&lt;/strong&gt; carga el modelo desde el archivo .xml, y aplica una tarea, &lt;strong&gt;GenStates.ajg&lt;/strong&gt;, escrita enwritten in AjBasic:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;for each StateModel in StateModels&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; TransformerManager.Transform(&amp;quot;State.tpl&amp;quot;,&amp;quot;TestHarness\${StateModel.ID}StateModel.cs&amp;quot;,Environment)&lt;br /&gt;end for&lt;/font&gt; 
&lt;p&gt;Hay otro comando, que podemos lanzar directamente desde la línea de comando, &lt;strong&gt;MakeStates.cmd&lt;/strong&gt;, conteniendo: 
&lt;p&gt;c:\ajlopez\ProyectosNet2\AjGenesis-0.5\bin\AjGenesis.Console TestHarness\Model.xml GenStates.ajg 
&lt;p&gt;Amo mi template AjBasic&amp;nbsp;en &lt;strong&gt;GenStates.ajg&lt;/strong&gt; ;-) un fragmento: 
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:1fdd4534-69ad-4611-9250-57e321cf751f" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections.Generic;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; Aabs;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; Core;

&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; ${StateModel.ID} {
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;enum&lt;/span&gt;&lt;span style="color:#000000;"&gt; ${StateModel.ID}States : &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    {
&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;#
    sep &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;for&lt;/span&gt;&lt;span style="color:#000000;"&gt; each State &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;in&lt;/span&gt;&lt;span style="color:#000000;"&gt; StateModel.States
#&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        ${sep}${State.ID}        &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; ${State.name}&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;#
        sep &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;,&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    end &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;for&lt;/span&gt;&lt;span style="color:#000000;"&gt;
#&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    } &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt; end enum ${StateModel.Id}States&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#000000;"&gt;
...
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Está basado en archivo .tt de Andrew Matthews. Notemos que no hay&amp;nbsp;referencia a nodos .XML o similares. AjGenesis carga el modelo en memoria, como un objeto dinámico. El lenguaje AjBasic puede acceder al modelo, usándolo como un&amp;nbsp;objecto cualquiera. El uso de &lt;strong&gt;${ }&lt;/strong&gt;&amp;nbsp;reemplaza la salida con algún valor, tomado de las variables o del modelo en proceso.&lt;/p&gt;
&lt;p&gt;El principal punto en este ejemplo es que está basado en un modelo libre (AjGenesis puede cargar cualquier modelo, no se usa uno predefinido). Si uno quiere agregar más información, podemos escribir más atributos, elementos, en el archivo .xml. Y usarlos desde el código de template. No hay un esquema fijo.&lt;/p&gt;
&lt;p&gt;Otro punto a destacar: el ejemplo podría ser modificado para generar la solución Visual Studio completa, o para generar una solución en otro lenguaje (un ejemplo generando una solución VS completa:&lt;br /&gt;&lt;a title="Code Generation for LINQ and C# 3.0 with AjGenesis" href="http://ajlopez.wordpress.com/2008/09/30/code-generation-for-linq-and-c-30-with-ajgenesis/"&gt;Code Generation for LINQ and C# 3.0 with AjGenesis&lt;/a&gt;&lt;br /&gt;)&lt;/p&gt;
&lt;p&gt;Gracias a Andrés por un ejemplo tan interesante. Pueden leer más sobre su implementación en el post mencionado:&lt;/p&gt;
&lt;p&gt;&lt;a title="Permanent Link to State Machines in C# 3.0 using T4 Templates" href="http://aabs.wordpress.com/2008/06/26/state-machines-in-c-30-using-t4-templates/"&gt;Permanent Link to State Machines in C# 3.0 using T4 Templates&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1651489" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Generaci_26002300_243_3B00_n+de+C_26002300_243_3B00_digo/default.aspx">Generaci&amp;#243;n de C&amp;#243;digo</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx">AjGenesis</category></item><item><title>Generación de código para LINQ y C# 3.0 con AjGenesis</title><link>http://msmvps.com/blogs/lopez/archive/2008/10/01/generaci-243-n-de-c-243-digo-para-linq-y-c-3-0-con-ajgenesis.aspx</link><pubDate>Wed, 01 Oct 2008 10:51:18 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1649363</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1649363</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2008/10/01/generaci-243-n-de-c-243-digo-para-linq-y-c-3-0-con-ajgenesis.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://www.ajlopez.com/ajgenesi" target="_blank"&gt;AjGenesis&lt;/a&gt;, mi proyecto open source de generación de código, usa un modelo definido por el usuario. Podemos definir tareas y templates, para transformar el modelo a código y archivos de texto. Podemos escribir nuestro propio modelo, agregar tareas y transformaciones. Desde una tarea, se puede invocar a objetos .NET o código AjBasic, en el medio del proceso de generación. Es un proceso flexible: genera lo que Ud. quiera generar, no tiene un patrón predeterminado.&lt;/p&gt; &lt;p&gt;Como el modelo lo define uno, el sistema no está limitado a un tipo de proyecto. Al estar basado en templates y tareas definidas, genera artefactos de código que no están ligados una sola tecnología. Podmos generar archivos para cualquier tecnología, framework, línea de negocios y plataforma. Podemos generar scripts de DDL, o una aplicación completa de base, o cualquier cosa en el medio. Es nuestra decisión hasta donde llegar.&lt;/p&gt; &lt;p&gt;Cuando comencé a escribir y usar el sistema, no existía .NET 2.0. Cuando la nueva tecnología se hizo pública, escribí tareas y templates adicionas para aprovechar las nuevas características como master pages, themes y nuevos controles ASP.NET, sin necesidad de tocar el código núcleo de AjGenesis. Una vez los nuevos templates y tareas estuvieron escritos, pude generar aplicaciones ASP.NET 2.x, a partir de los mismos modelos que ya tenía armados para mis otros cursos y trabajos.&lt;/p&gt; &lt;p&gt;Ahora, como una prueba de concepto, escribí un nuevo ejemplo, que genera código usando LINQ, en nuevo chico en el barrio de .NET 3.x. El resultado fue publicado como AjGenesisExamplesNet3.zip en la página de&amp;nbsp;&amp;nbsp;&lt;a href="http://www.codeplex.com/ajgenesis/Release/ProjectReleases.aspx?ReleaseId=7261" target="_blank"&gt;ejemplos de AjGenesis en CodePlex&lt;/a&gt;. Para ejecutar el ejemplo, necesitamos la&amp;nbsp;&lt;a href="http://www.codeplex.com/ajgenesis/Release/ProjectReleases.aspx?ReleaseId=7262" target="_blank"&gt;actual versión 0.5&lt;/a&gt;&amp;nbsp;(incluye código fuente, ejemplos iniciales, y binarios). (Hay una versión 0.5.1 en desarrollo que pueden ir viendo en &lt;a href="http://www.codeplex.com/ajgenesis/SourceControl/ListDownloadableCommits.aspx" target="_blank"&gt;el repositorio de código del proyecto&lt;/a&gt;).&lt;/p&gt; &lt;h3&gt;El ejemplo&lt;/h3&gt; &lt;p&gt;&lt;img style="margin:0px 20px 20px 0px;" src="http://www.todocontenidos.com/images/articles/ajgenesisnet3dir.png" alt="" /&gt;&lt;/p&gt; &lt;p&gt;Hay sólo un modelo en el ejemplo: AjFirstExample, con un simple modelo XML describiendo a dos entidades planas, Customers y Suppliers. Es el mismo modelo que usé en otros ejemplos anteriores.&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:30955e46-f9ad-4f79-a01b-42bcb25fff5c" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Project&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;AjFirstExample&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Description&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;First Example using AjGenesis&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Description&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Prefix&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;AjFE&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Prefix&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Domain&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;com.ajlopez&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Domain&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;CompanyName&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;ajlopez&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;CompanyName&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Model&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Entities&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Entity &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Source&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Entities/Customer.xml&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Entity &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Source&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Entities/Supplier.xml&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Entities&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Lists&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;List &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Entity&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Customer&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;List &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Entity&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Supplier&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Lists&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Forms&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Form &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Entity&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Customer&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Form &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Entity&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Supplier&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Forms&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Views&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;View &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Entity&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Customer&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;View &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Entity&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Supplier&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Views&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Model&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Project&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;El directorio Templates contiene dos conjuntos de archivos .tpl&amp;nbsp;, que son templates AjGenesis. Los de MsSql son usados en la generación de scripts DDL. En el folder CSharp3, hay nuevos templates que generan un LINQ DataContext, y clases simples, como entidades y servicios.&lt;/p&gt;
&lt;h3&gt;Ejecutando el ejemplo&lt;/h3&gt;
&lt;p&gt;El directorio principal del ejemplo hay un archivo de comando:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;makeajfirstexample.cmd&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;que al ejecutarse, carga el modelo abstracto y el de tecnología en memoria, y&amp;nbsp;ejecuta dos tareas, creando códidog y scripts de generación de base de datos.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajfirstexamplenet3cmd.png" alt="" /&gt; 
&lt;p&gt;Lo generado reside en un nuevo directorio Build, con código fuente y scripts para MS SQL: 
&lt;p align="left"&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajfirstexamplenet3bld.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;El archivo Build\AjFirstExample\CSharp3\Sql\CreateDatabase.sql crea la base y tablas, un fragmento:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:71309bad-5e97-4183-902e-bf846b13c171" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;create&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;database&lt;/span&gt;&lt;span style="color:#000000;"&gt; AjFirstExampleNet3
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;go&lt;/span&gt;&lt;span style="color:#000000;"&gt;

...

&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;use&lt;/span&gt;&lt;span style="color:#000000;"&gt; AjFirstExampleNet3
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;go&lt;/span&gt;&lt;span style="color:#000000;"&gt;

...

&lt;/span&gt;&lt;span style="color:#008080;"&gt;--
--&lt;/span&gt;&lt;span style="color:#008080;"&gt;        Entity:        Customer&lt;/span&gt;&lt;span style="color:#008080;"&gt;
--&lt;/span&gt;&lt;span style="color:#008080;"&gt;        Description:    Customer Entity&lt;/span&gt;&lt;span style="color:#008080;"&gt;
--
&lt;/span&gt;&lt;span style="color:#000000;"&gt;

&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;exists&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;select&lt;/span&gt;&lt;span style="color:#000000;"&gt; name &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;from&lt;/span&gt;&lt;span style="color:#000000;"&gt; sysobjects 
         &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;where&lt;/span&gt;&lt;span style="color:#000000;"&gt; name &lt;/span&gt;&lt;span style="color:#808080;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Customer&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;and&lt;/span&gt;&lt;span style="color:#000000;"&gt; type &lt;/span&gt;&lt;span style="color:#808080;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;U&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;drop&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;table&lt;/span&gt;&lt;span style="color:#000000;"&gt; Customer
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;go&lt;/span&gt;&lt;span style="color:#000000;"&gt;

&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;create&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;table&lt;/span&gt;&lt;span style="color:#000000;"&gt; Customer (
        &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;[&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Id&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;]&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;[&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;uniqueidentifier&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;]&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#808080;"&gt;not&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt; 
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;CONSTRAINT&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;[&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;DF_Customer_id&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;]&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;DEFAULT&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;newid&lt;/span&gt;&lt;span style="color:#000000;"&gt;()),    
        &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;[&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;]&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;font-weight:bold;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:#000000;"&gt;(&lt;/span&gt;&lt;span style="color:#800000;font-weight:bold;"&gt;200&lt;/span&gt;&lt;span style="color:#000000;"&gt;),    
        &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;[&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Address&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;]&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;font-weight:bold;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:#000000;"&gt;(&lt;/span&gt;&lt;span style="color:#800000;font-weight:bold;"&gt;2048&lt;/span&gt;&lt;span style="color:#000000;"&gt;),    
        &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;[&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Notes&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;]&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;font-weight:bold;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:#000000;"&gt;(&lt;/span&gt;&lt;span style="color:#800000;font-weight:bold;"&gt;2048&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
 &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;CONSTRAINT&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;[&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;PK_Customer&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;]&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;PRIMARY&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;KEY&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;CLUSTERED&lt;/span&gt;&lt;span style="color:#000000;"&gt; 
(
    &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;[&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Id&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;]&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ASC&lt;/span&gt;&lt;span style="color:#000000;"&gt;
)&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;WITH&lt;/span&gt;&lt;span style="color:#000000;"&gt; (PAD_INDEX  &lt;/span&gt;&lt;span style="color:#808080;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;OFF&lt;/span&gt;&lt;span style="color:#000000;"&gt;, IGNORE_DUP_KEY &lt;/span&gt;&lt;span style="color:#808080;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;OFF&lt;/span&gt;&lt;span style="color:#000000;"&gt;) 
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;ON&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;[&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;PRIMARY&lt;/span&gt;&lt;span style="color:#FF0000;"&gt;]&lt;/span&gt;&lt;span style="color:#000000;"&gt;
)
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;go&lt;/span&gt;&lt;span style="color:#000000;"&gt;

&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p align="left"&gt;La solución puede cargarse directamente en Visual Studio 2008:&lt;/p&gt;
&lt;p align="left"&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajfirstexamplenet3sln.png" alt="" /&gt; &lt;/p&gt;
&lt;p align="left"&gt;La clase AjFirstExampleDataContext.cs es un simple LINQ DataContext:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:ac463baa-7e19-431b-bbba-a80824bcb120" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;partial&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; AjFirstExampleDataContext : 
        System.Data.Linq.DataContext
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; AjFirstExampleDataContext() 
....
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Table&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Customer&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; Customers;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Table&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Supplier&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; Suppliers;
    }

&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Podríamos reemplazarlo por un DataContext generado por el wizard de Linq To SQL que viene en el Visual Studio. Hay una opción en el modelo de tecnología para especificar qué estrategia usar: o genera un archivo nuestro, o deja al desarrollador poner manualmen luego, al levantar la solución, un DataContext generado por el propio IDE. El resto de las clases funciona igual contra cualquiera de las dos opciones.&lt;/p&gt;
&lt;p&gt;La solución tiene 3 proyectos: datos, servicios y presentación ASP.NET. La página inicial es espartana (ya me conocen, soy desarrollador, no diseñador gráfico... :-)):&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajfirstexamplenet3pag.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Desde la opción de Administration, podemos explorar, agregar, editar y borrar clientes y proveedores:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajfirstexamplenet3cus.png" alt="" /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Próximos pasos&lt;/h3&gt;
&lt;p&gt;Quiero convertir otros ejemplos anteriores a estos nuevos templates (el modelo de AjTest es el más desafiante, con relaciones uno a varios y varias entidades). Sería interesante generar páginas ASP.NET MVC, en lugar de ASP.NET plano. Y algunos proyectos adicionales, de infraestructura de testo. Estoy viendo el código de &lt;a href="http://www.codeplex.com/ScrumLite" target="_blank"&gt;ScrumLite&lt;/a&gt; como un ejemplo base a seguir.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://delicious.com/ajlopez"&gt;http://delicious.com/ajlopez&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;br /&gt;&lt;a title="http://friendfeed.com/ajlopez" href="http://friendfeed.com/ajlopez"&gt;http://friendfeed.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1649363" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Generaci_26002300_243_3B00_n+de+C_26002300_243_3B00_digo/default.aspx">Generaci&amp;#243;n de C&amp;#243;digo</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx">AjGenesis</category></item><item><title>Modelo textual para generación de código con AjGenesis</title><link>http://msmvps.com/blogs/lopez/archive/2008/09/29/modelo-textual-para-generaci-243-n-de-c-243-digo-con-ajgenesis.aspx</link><pubDate>Mon, 29 Sep 2008 04:33:57 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1649127</guid><dc:creator>lopez</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1649127</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2008/09/29/modelo-textual-para-generaci-243-n-de-c-243-digo-con-ajgenesis.aspx#comments</comments><description>&lt;p&gt;Estuve trabajando agregando una &amp;quot;feature&amp;quot; a &lt;a href="http://www.ajlopez.com/ajgenesis"&gt;mi proyecto de generación de código AjGenesis&lt;/a&gt;. El sistema maneja un modelo definido por el usuario, que puede ser cargado en memoria desde archivos .xml. AjGenesis puede procesar el modelo, completarlo, invocar a objetos .NET, crear directorios, archivos y aplicar templates para crear código y archivos de texto cualesquiera.&lt;/p&gt; &lt;p&gt;Pero el modelo reside en memoria: la deserialización desde XML es solamente una opción de implementación. Este fin de semana, he agregado el nuevo código en el&amp;nbsp;&lt;a href="http://www.codeplex.com/ajgenesis"&gt;repositorio de código del proyecto&amp;nbsp;Codeplex&lt;/a&gt;: ahora, todo usuario de AjGenesis puede expresar su modelo en texto plano.&lt;/p&gt; &lt;p align="center"&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgenesiscodeplex.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;El modelo puede, entonces, expresarse en simples archivos de texto. Veamos un ejemplo.&lt;/p&gt; &lt;p&gt;El ejemplo más simple que se me ocurre es el modelo para &lt;a href="http://msmvps.com/blogs/lopez/archive/2006/11/19/generando-c-digo-hello-world-con-ajgenesis.aspx" target="_blank"&gt;una aplicación Hello World en AjGenesis&lt;/a&gt;. El modelo en XML es:&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:f37f5c33-9a32-4458-8ba2-23a563355b90" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Project &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Company&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;ajlopez.com&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Message&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Hello, World&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Message&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Project&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ahora, podemos expresar el mismo modelo en un archivo de texto:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:e2a1ed03-e576-4515-8fe1-7329ee1b0893" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;Project
    Company &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;ajlopez.com&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    Message &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Hello, World&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
End Project
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Si necesitamos más mensajes, en XML escribíamos:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:49a0b1f6-dde2-4bfe-a9f5-7eba1d739dce" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Project&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Messages&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Message&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Hello, World One&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Message&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Message&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Hello, World Two&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Message&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Message&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Hello, World Three&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Message&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Messages&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Project&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Ahora, en texto, podemos escribir:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:6822ba95-44d6-4cf9-9ffe-a3aaac06c90c" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;Project
    Messages
        Message &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Hello, World One&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        Message &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Hello, World Two&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        Message &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Hello, World Three&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    End Messages
End Project
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Se puede cargar el modelo desde el programa de consola, indicando un archivo .txt o .xml:&lt;/p&gt;
&lt;p&gt;&lt;font face="Consolas"&gt;..\..\..\bin\AjGenesis.Console Model.txt ModuleVb.tpl HelloWorld.vb&lt;/font&gt; 
&lt;p&gt;&lt;font face="Consolas"&gt;..\..\..\bin\AjGenesis.Console Model.xml ModuleVb.tpl HelloWorld.vb&lt;/font&gt; 
&lt;p&gt;Lo mismo podemos hacer desde tareas de NAnt: cargar un modelo, en un archivo .XML o .txt.&lt;/p&gt;
&lt;p&gt;Hay más ejemplos en:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeplex.com/ajgenesis/SourceControl/DirectoryView.aspx?SourcePath=%24%2fajgenesis%2fexamples%2fHelloWorld&amp;amp;changeSetId=40723" target="_blank"&gt;Hello world Examples&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Un modelo más realista, donde describimos entidades en un XML:&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:49a47975-f343-4c9c-a68f-a2895e097664" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#FF00FF;"&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#008000;"&gt;&amp;lt;!--&lt;/span&gt;&lt;span style="color:#008000;"&gt; 
  An Entity with Properties
  &lt;/span&gt;&lt;span style="color:#008000;"&gt;--&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Entities&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Entity &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Customer&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Description&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;A Customer&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Description&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Properties&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Property &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Id&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Id&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Property &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Name&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Text&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Property &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Address&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Text&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Properties&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Entity&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Entity &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Supplier&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Description&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;A Supplier&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Description&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Properties&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Property &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Id&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Id&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Property &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Name&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Text&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
      &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Property &lt;/span&gt;&lt;span style="color:#FF0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Address&amp;quot;&lt;/span&gt;&lt;span style="color:#FF0000;"&gt; Type&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;=&amp;quot;Text&amp;quot;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Properties&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
  &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Entity&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Entities&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ahora puede ser expresado en texto (no es el mismo modelo de arriba, pero similar):&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:65a2cfc5-da18-4dd4-97b2-ad87289a03ac" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;Entities

    Entity Customer
        Description &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Customer Entity&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        Properties
            Property Id Type&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Id&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            Property Name Type&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Text&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            Property Address Type&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Text&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        End Properties
    End Entity

    Entity Supplier
        Description &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Supplier Entity&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        Properties
            Property Id Type&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Id&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            Property Name Type&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Text&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
            Property Address Type&lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Text&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
        End Properties
    End Entity

End Entities

&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Una vez que el modelo es cargado en memoria, AjGenesis lo procesa como siempre, sin importar su forma original, texto o XML.&lt;/p&gt;
&lt;p&gt;Más sobre AjGenesis:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://ajlopez.wordpress.com/category/ajgenesis/" target="_blank"&gt;Posts about AjGenesis&lt;/a&gt;&amp;nbsp;(English)&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx" target="_blank"&gt;Posts sobre AjGenesis&lt;/a&gt; (Spanish)&lt;/p&gt;
&lt;p&gt;Apenas relacionado, pero interesante:&lt;/p&gt;
&lt;p&gt;&lt;a title="Problems for Textual Model Notations" href="http://metabubble.blogspot.com/2007/06/problems-for-textual-model-notations.html"&gt;Problems for Textual Model Notations&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1649127" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx">AjGenesis</category></item></channel></rss>