<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-23470706</id><updated>2012-01-27T21:28:24.179-08:00</updated><category term='Crystal Reports'/><category term='NMock'/><category term='Windows Authentication'/><category term='Podcast'/><category term='.Net'/><category term='Moq'/><category term='AltNet5'/><category term='RubyOnRails'/><category term='TestsEx'/><category term='ASP.NET MVC'/><category term='ASP.NET'/><category term='Coca-Cola'/><category term='MongoDB'/><category term='MEF'/><category term='TDD'/><category term='Cucumber'/><category term='BDD'/><category term='DBX4'/><category term='e-mail'/><category term='Delphi'/><category term='Unity'/><category term='Visual Basic'/><category term='Refactorización'/><category term='Office 2007'/><category term='IBExpert'/><category term='Cdf'/><category term='LinqToSql'/><category term='TJNET'/><category term='NUnit'/><category term='jQuery'/><category term='Trabajo'/><category term='personal'/><category term='IoC'/><category term='OpenXML'/><category term='Unit Test'/><category term='Sql Server'/><category term='programacion'/><category term='MVP'/><category term='XML'/><category term='Munq'/><category term='dev3cast'/><category term='NetBeans'/><category term='Web 2.0'/><category term='C#'/><category term='CodeGear'/><category term='FluentValidation'/><category term='moking'/><category term='NuGet'/><category term='Ruby'/><category term='teclado'/><category term='Database'/><category term='Linq'/><category term='razor'/><category term='OpenOffice.org'/><category term='XML Literals'/><category term='Firebird'/><category term='JavaScript'/><category term='magmarails'/><category term='C++ Builder'/><category term='base de datos'/><category term='Database Mail'/><title type='text'>Mario Cornejo</title><subtitle type='html'>Notas sobre el desarrollo de software</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.developeando.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.developeando.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>88</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-23470706.post-1676178876305732523</id><published>2012-01-27T09:10:00.001-08:00</published><updated>2012-01-27T09:11:51.493-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Iniciando con jQuery</title><content type='html'>&lt;p&gt;He estado pensando en escribir alguno que otro post sobre JavaScript. No digo que vaya a empezar una serie ni mucho menos (luego las dejo a medias) pero si escribir algunos post. Así que iniciamos por el principio. Lo básico de &lt;a href="http://jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;El ejemplo será una lista de comentarios a la cual le quisiéramos ir agregando elementos a la lista. Tenemos el siguiente HTML:&lt;/p&gt; &lt;pre style="background: #ffffff; color: #000000"&gt;&lt;span style="color: #a65700"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;html&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;head&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #a65700"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;title&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;Comentarios&lt;span style="color: #a65700"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;title&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;    &lt;br /&gt;    &lt;span style="color: #a65700"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;head&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;body&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #a65700"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;ul&lt;/span&gt;&lt;span style="color: #274796"&gt; &lt;/span&gt;&lt;span style="color: #074726"&gt;id&lt;/span&gt;&lt;span style="color: #808030"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6"&gt;&amp;quot;comments&amp;quot;&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #a65700"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;li&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;Comentario &lt;span style="color: #008c00"&gt;1&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;li&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #a65700"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;li&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;Comentario &lt;span style="color: #008c00"&gt;2&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;li&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #a65700"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;ul&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;    &lt;br /&gt;        &lt;span style="color: #a65700"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;input&lt;/span&gt;&lt;span style="color: #274796"&gt; &lt;/span&gt;&lt;span style="color: #074726"&gt;id&lt;/span&gt;&lt;span style="color: #808030"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6"&gt;&amp;quot;comment&amp;quot;&lt;/span&gt;&lt;span style="color: #274796"&gt; &lt;/span&gt;&lt;span style="color: #074726"&gt;type&lt;/span&gt;&lt;span style="color: #808030"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6"&gt;&amp;quot;text&amp;quot;&lt;/span&gt;&lt;span style="color: #274796"&gt; &lt;/span&gt;&lt;span style="color: #a65700"&gt;/&amp;gt;&lt;/span&gt; &lt;br /&gt;        &lt;span style="color: #a65700"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;button&lt;/span&gt;&lt;span style="color: #274796"&gt; &lt;/span&gt;&lt;span style="color: #074726"&gt;id&lt;/span&gt;&lt;span style="color: #808030"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6"&gt;&amp;quot;add&amp;quot;&lt;/span&gt;&lt;span style="color: #274796"&gt; &lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;Agregar&lt;span style="color: #a65700"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;button&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;         &lt;br /&gt;    &lt;span style="color: #a65700"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;body&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;    &lt;br /&gt;&lt;span style="color: #a65700"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;html&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;La intención es que cuando el usuario haga clic en el botón “Agregar” se agregue lo escrito en la caja de texto a la lista de comentarios.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Lo primero que debemos hacer es agregar la referencia al código de &lt;a href="http://jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt;. Podemos usar una copia local o hacer uso de alguna red de distribución de contenidos (&lt;a href="http://es.wikipedia.org/wiki/Red_de_entrega_de_contenidos" target="_blank"&gt;CDN&lt;/a&gt;).&lt;/p&gt;&lt;br /&gt;&lt;pre style="background: #ffffff; color: #000000"&gt;&lt;span style="color: #a65700"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035"&gt;script&lt;/span&gt; &lt;span style="color: #274796"&gt;src&lt;/span&gt;&lt;span style="color: #808030"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #0000e6"&gt;http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js&lt;/span&gt;&lt;span style="color: #0000e6"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035"&gt;script&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;con esto ya podemos hacer uso de jQuery. Así que agregamos un bloque de script a nuestra página para agregar la funcionalidad que requerimos.&lt;/p&gt;&lt;br /&gt;&lt;pre style="background: #ffffff; color: #000000"&gt;&lt;span style="color: #a65700"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;script&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    $&lt;span style="color: #808030"&gt;(&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;function&lt;/span&gt; &lt;span style="color: #808030"&gt;(&lt;/span&gt;&lt;span style="color: #808030"&gt;)&lt;/span&gt; &lt;span style="color: #800080"&gt;{&lt;/span&gt;&lt;br /&gt;        $&lt;span style="color: #808030"&gt;(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #0000e6"&gt;#add&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #808030"&gt;)&lt;/span&gt;&lt;span style="color: #808030"&gt;.&lt;/span&gt;click&lt;span style="color: #808030"&gt;(&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;function&lt;/span&gt; &lt;span style="color: #808030"&gt;(&lt;/span&gt;&lt;span style="color: #808030"&gt;)&lt;/span&gt; &lt;span style="color: #800080"&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #800000; font-weight: bold"&gt;var&lt;/span&gt; newCommentTextBox &lt;span style="color: #808030"&gt;=&lt;/span&gt; $&lt;span style="color: #808030"&gt;(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #0000e6"&gt;#comment&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #808030"&gt;)&lt;/span&gt;&lt;span style="color: #800080"&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #800000; font-weight: bold"&gt;var&lt;/span&gt; commentText &lt;span style="color: #808030"&gt;=&lt;/span&gt; newCommentTextBox&lt;span style="color: #808030"&gt;.&lt;/span&gt;val&lt;span style="color: #808030"&gt;(&lt;/span&gt;&lt;span style="color: #808030"&gt;)&lt;/span&gt;&lt;span style="color: #800080"&gt;;&lt;/span&gt;&lt;br /&gt;            $&lt;span style="color: #808030"&gt;(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #0000e6"&gt;#comments&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #808030"&gt;)&lt;/span&gt;&lt;span style="color: #808030"&gt;.&lt;/span&gt;append&lt;span style="color: #808030"&gt;(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #0000e6"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color: #808030"&gt;+&lt;/span&gt; commentText &lt;span style="color: #808030"&gt;+&lt;/span&gt; &lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #0000e6"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #808030"&gt;)&lt;/span&gt;&lt;span style="color: #800080"&gt;;&lt;/span&gt;&lt;br /&gt;            newCommentTextBox&lt;span style="color: #808030"&gt;.&lt;/span&gt;val&lt;span style="color: #808030"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6"&gt;''&lt;/span&gt;&lt;span style="color: #808030"&gt;)&lt;/span&gt;&lt;span style="color: #800080"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #800080"&gt;}&lt;/span&gt;&lt;span style="color: #808030"&gt;)&lt;/span&gt;&lt;span style="color: #800080"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #800080"&gt;}&lt;/span&gt;&lt;span style="color: #808030"&gt;)&lt;/span&gt;&lt;span style="color: #800080"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a65700"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold"&gt;script&lt;/span&gt;&lt;span style="color: #a65700"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Lo primero que hacemos es pasar como parámetro a la función “$” de jQuery una función que queremos que se ejecute al cargarse la página. Dentro de esta función tenemos la línea &lt;em&gt;$(“#add”).click(function () {&lt;/em&gt; que lo que hace es primero buscar al elemento con &lt;em&gt;id=“add”&lt;/em&gt;&amp;#160; (en este caso el botón) después llamar el método &lt;em&gt;click&lt;/em&gt; y pasarle la función que queremos ejecutar cuando se haga un clic en el elemento.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Dentro de la función buscamos el elemento id=“comment” (que es la caja de texto) y obtenemos su contenido con la función &lt;em&gt;val()&lt;/em&gt;. Después agregamos un elemento más a la lista de comentarios (id=&amp;quot;comments&amp;quot;) con el texto que obtuvimos de la caja de texto. Por último limpiamos la caja de texto con &lt;em&gt;newCommentTextBox&lt;span style="color: #808030"&gt;.&lt;/span&gt;val&lt;span style="color: #808030"&gt;(&lt;/span&gt;&lt;span style="color: #0000e6"&gt;''&lt;/span&gt;&lt;span style="color: #808030"&gt;)&lt;/span&gt;&lt;span style="color: #800080"&gt;;&lt;/span&gt;&lt;/em&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Espero que este post sirva para que quienes aun no se animan a entrarle a JavaScript vean lo fácil que es, empiecen a perderle el miedo y aprovechen las ventajas que tiene. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-1676178876305732523?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/1676178876305732523/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=1676178876305732523' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1676178876305732523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1676178876305732523'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2012/01/iniciando-con-jquery.html' title='Iniciando con jQuery'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-4190396402295385539</id><published>2012-01-24T17:08:00.001-08:00</published><updated>2012-01-24T17:15:18.846-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moking'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>Probando sin mocking framework</title><content type='html'>&lt;p&gt;Al estar trabajando en un proyecto sobre ASP.NET MVC pequeño. Pensé que sería mas fácil animar a escribir pruebas, a personas que no están acostumbradas, si al escribirlas no necesitaran usar librerías externas. Como son los mocking frameworks y las librerías para las aserciones. Así que decidí escribir las pruebas unitarias usando solo las herramientas que me brinda Visual Studio. Eso significa usar msTest y escribir implementaciones falsas de las dependencias de los sistemas bajo prueba.&lt;/p&gt;  &lt;p&gt;Llegué a pensar que eso significaría escribir mucho más código ya que tendría que proporcionar varías implementaciones que un mocking framework me ahorraría. Sin embargo he notado que la cantidad de código no es mucho más. Ya que con las mocking frameworks necesitaba hacer más setups dentro del test. Es claro que tiene sus ventajas y desventajas.&lt;/p&gt;  &lt;p&gt;Noté que para un programador, que no esta acostumbrado a escribir pruebas unitarias, es fácil entender qué es lo que pasa cuando usamos una implementación falsa donde puede ver el código. A la vez es fácil que escriba sus implementaciones que solo le sirven para pruebas. En ocasiones cuando trataba de explicar TDD (a gente que no esta acostumbrada) usando un mocking framework, u otra librería, notaba que varios se perdían un poco tratando de entender el código de setups de moq o de NSubstitute. Con implementaciones falsas escritas por ellos mismos (o que pueden ver lo que pasa) es más fácil concentrarse en (y encontrarle más sentido a) la prueba.&lt;/p&gt;  &lt;p&gt;El método de prueba puede centrarse en los efectos secundarios del sistema bajo prueba, en lugar de la implementación. Es decir no pruebas que realice llamadas a ciertos métodos de las dependencias sino que tenga los efectos secundarios que se espera.&lt;/p&gt;  &lt;p&gt;Una de las desventajas es que se necesita escribir la implementación falsa para que la prueba pueda correr y eso hace que pierda un poco el flujo de lo que se esta probando. Al tener que abrir otro archivo y escribir algo de código. Además que terminas con más código que mantener.&lt;/p&gt;  &lt;p&gt;Otra es que a pesar de tener una implementación falsa que se puede compartir. De cualquier forma se necesita algo de código en la prueba para cumplir con las precondiciones que la prueba requiere y terminas con la implementación falsa además de código de setup. Otra vez más código que quizás el mocking framework me hubiera ahorrado.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-4190396402295385539?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/4190396402295385539/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=4190396402295385539' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4190396402295385539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4190396402295385539'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2012/01/probando-sin-mocking-framework.html' title='Probando sin mocking framework'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-4335496457976037494</id><published>2012-01-13T15:22:00.001-08:00</published><updated>2012-01-13T16:15:01.412-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>¿Seguir usando Delphi?</title><content type='html'>&lt;p&gt;Aun mantengo y agrego nueva funcionalidad a una aplicación que desarrollé hace algunos años usando Delphi. Específicamente con &lt;a href="http://www.developeando.com/2006/08/vuelven-los-turbo.html" target="_blank"&gt;Turbo Delphi&lt;/a&gt;, basado en la versión 2006 del entonces conocido como &lt;a href="http://delphi.wikia.com/wiki/Borland_Developer_Studio_2006" target="_blank"&gt;Borland Developer Studio&lt;/a&gt;. En realidad no se trata de una sola aplicación sino de una familia de aplicaciones para la administración de un negocio de venta al menudeo y medio mayoreo.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-z33_ogewXPI/TxC8uHV0bII/AAAAAAAAAYw/avZHKhBPqsg/s1600-h/producto13.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="producto" border="0" alt="producto" src="http://lh5.ggpht.com/-z_PKjB250S4/TxC8uqaO-HI/AAAAAAAAAY4/PQlgSGTLgkg/producto_thumb11.png?imgmax=800" width="324" height="254" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Sigo agregando nuevas características, conforme las necesidades de la empresa, lo cual no es muy seguido. Cada vez que tengo que agregar alguna funcionalidad me pregunto ¿Debería migrar el código fuente a alguna otra tecnología?&lt;/p&gt;  &lt;h3&gt;¿Por qué cambiar?&lt;/h3&gt;  &lt;p&gt;Bueno si funciona ¿Para que cambiar? es la otra pregunta que me hago inmediatamente después de pensar en migrar. Las razones son:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Mi forma personal de programar ha cambiado&lt;/strong&gt;: al usar Delphi debo regresar a usar objetos como datasets, escribir SQL a mano (Sin &lt;a href="http://es.wikipedia.org/wiki/Mapeo_objeto-relacional" target="_blank"&gt;ORM’s&lt;/a&gt;), mucho arrastrar y soltar para después modificar propiedades en el object inspector. Cuando lo que quisiera hacer es utilizar características de lenguajes y frameworks nuevos. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Documentación&lt;/strong&gt;: Ya que no es una tecnología que use todos los días, cada vez que regreso a algún proyecto y necesito agregar algo de código o modificar alguna propiedad necesito buscar documentación para saber cual es la manera Delphi de hacerlo. No quiero escribir mucho código para algo que con cambiar alguna propiedad o arrastrar un componente hubiera bastado. No es mucha la documentación que se encuentra y la mayoría de esta es vieja o trata las nuevas características que aun salen para Delphi. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Precio&lt;/strong&gt;: Otra razón para no migrar a una &lt;a href="http://www.embarcadero.com/products/delphi" target="_blank"&gt;versión más reciente de Delphi&lt;/a&gt; (ahora parte de Embarcadero) es el precio de la licencia. Es más cara que una licencia de VisualStudio y siento que con VS puedo hacer más cosas que solo escribir aplicaciones de escritorio. Además de que las puedo desarrollar de una manera “moderna”. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;La tecnología puede llegar a ser obsoleta&lt;/strong&gt;: Al seguir desarrollando en la versión actual corro el riesgo de no encontrar soporte, alguien que pueda ayudarme, cuando necesite realizar algo que no este soportado en la tecnología actual. Como puede ser la integración con sistemas más “modernos”. &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;¿Por qué seguir en Delphi?&lt;/h3&gt;  &lt;p&gt;Aun con las desventajas que tiene el mantener la aplicación en una tecnología “vieja” creo que tiene ciertas ventajas mantener el código donde esta:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;La aplicación funciona&lt;/strong&gt;:Esta es la principal razón por la que sigo usando Delphi para esos proyectos. Aun no se ha presentado problemas graves por estar usando esa tecnología. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Tiempo de desarrollo&lt;/strong&gt;: Es más rápido agregar características a las aplicaciones usando la tecnología actual que reescribir todo en alguna tecnología “nueva”. Además el código no esta mal/feo es relativamente fácil de seguir o de modificar para después agregar nueva funcionalidad. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Costo-Beneficio&lt;/strong&gt;: Al final todo se reduce al costo beneficio. No estoy convencido que el costo que implica reescribir toda (o gran parte) de la aplicación tenga un beneficio que valga la pena el gasto. Si bien es posible que en un futuro sea más fácil seguir usando una tecnología moderna; por el momento no ha causado un problema seguir desarrollando en Delphi. Solo alguno que otro enojo (como programador) por no poder usar lambdas o cosas así. &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Conclusión&lt;/h3&gt;  &lt;p&gt;Al no poder justificar completamente el gasto creo que seguiré desarrollando (por el momento) las aplicaciones principales en Delphi mientras me sea posible. Quizás haga proyectos pequeños, relacionados, usando alguna otra tecnología (como .Net) para ir migrando poco a poco. Pero sin descuidar que el desarrollo principal en estos proyectos es en Delphi. Aun sigo considerando también comprar la versión más reciente de Delphi aunque es lo menos probable.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-4335496457976037494?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/4335496457976037494/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=4335496457976037494' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4335496457976037494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4335496457976037494'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2012/01/seguir-usando-delphi.html' title='¿Seguir usando Delphi?'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/-z_PKjB250S4/TxC8uqaO-HI/AAAAAAAAAY4/PQlgSGTLgkg/s72-c/producto_thumb11.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-6069936814387262437</id><published>2012-01-06T14:10:00.001-08:00</published><updated>2012-01-06T14:23:01.703-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trabajo'/><title type='text'>Programando en laptop</title><content type='html'>&lt;p&gt;Llevo varios días trabajando exclusivamente desde la laptop, sin teclado ni monitor externo. Esto es principalmente porque el monitor externo ha estado fallando últimamente y porque he estado trabajando desde varios lugares de la casa. &lt;/p&gt;  &lt;p&gt;Me ha gustado la experiencia de usar solo la laptop, lo limpio que se ve el escritorio sin los cables del monitor. Es fácil cerrar la laptop y moverme al sofá o incluso a la cocina. Además de que me estoy acostumbrando a trabajar con las limitaciones del teclado/mouse pero estoy aprovechando las ventajas de no tener que cargar con más equipo y poder trabajar desde donde sea. Ahora tecleo más lento pero no he visto que afecte el trabajo del día [soy desarrollador, no secretaria ;-)].&lt;/p&gt;  &lt;p&gt;Algunos aspectos que he empezado a considerar tratando de decidir si debo comprar otro monitor o seguir trabajando solo con la laptop son:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Movilidad&lt;/strong&gt;: Trabajando solo usando la laptop me permite trabajar desde cualquier parte (cualquier habitación de la casa, oficina, en una cafetería, etc.). Al trabajar con un monitor, teclado, mouse externo necesito conectar/desconectar cada que quiero moverme de lugar.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Comodidad&lt;/strong&gt;: Es más cómodo trabajar con 2 monitores (sobre todo porque el monitor externo es grande) , con mouse y &lt;a href="http://www.developeando.com/2011/12/teclado-en-espanol-latinoamerica.html" target="_blank"&gt;teclado externo&lt;/a&gt;. Sin embargo también es cómodo poder trabajar desde cualquier parte. Llegué a pensar que solo es cuestión de acostumbrarme; pero cuando trabajo varios días solo con la laptop aparece un dolor detrás del cuello que es muy molesto. Aunque supongo que hay maneras de evitarlo. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Económico&lt;/strong&gt;: Es más barato no comprar monitor externo y trabajar directamente desde la laptop. También he considerado comprar una computadora de escritorio para trabajar en la oficina/casa y dejar la laptop para cosas personales o cuando requiera moverme, aunque para ese caso me sale más barato solo comprar el monitor externo y no toda la computadora.&lt;/p&gt;  &lt;p&gt;Aun no he decidido que haré…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-6069936814387262437?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/6069936814387262437/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=6069936814387262437' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6069936814387262437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6069936814387262437'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2012/01/programando-en-laptop.html' title='Programando en laptop'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-8476550519977213392</id><published>2011-12-30T11:15:00.001-08:00</published><updated>2011-12-30T11:23:36.716-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trabajo'/><category scheme='http://www.blogger.com/atom/ns#' term='teclado'/><title type='text'>Teclado en español Latinoamérica</title><content type='html'>&lt;p&gt;Cuando empecé a utilizar computadoras lo hacia únicamente con &lt;a href="http://en.wikipedia.org/wiki/File:KB_United_States-NoAltGr.svg" target="_blank"&gt;teclados en ingles (EN-US)&lt;/a&gt; ya que al vivir en Tijuana (frontera con San Diego) era más fácil (y barato) conseguir teclados en ese idioma. Ademas todos los programas que utilizaba estaban en ingles. En esa época era común el uso de (alt+164) para las ´ñ’ y otros códigos más. &lt;/p&gt;  &lt;p&gt;Como programador seguía con el &lt;a href="http://en.wikipedia.org/wiki/File:KB_United_States-NoAltGr.svg" target="_blank"&gt;teclado EN-US&lt;/a&gt; cuando trabajaba desde la “oficina” de la empresa. Como parte de un proyecto tuve que estar en sitio por varios meses en una empresa de la cuidad donde las estaciones de trabajo todas tenían &lt;a href="http://en.wikipedia.org/wiki/File:KB_Latin_American.svg" target="_blank"&gt;teclados en español Latinoamérica&lt;/a&gt;. Durante algún tiempo batallé para acostumbrarme, sentía que odiaba los teclados en español. Recuerdo que un &lt;a href="http://twitter.com/#!/t1n0_29" target="_blank"&gt;amigo&lt;/a&gt; en la universidad usaba un teclado en español en su casa y me llamaba la atención por qué alguien haría eso a propósito, pudiendo usar un teclado en ingles. Recuerdo, también, que me comentó lo fácil que era escribir la ‘ñ’, los acentos, signos de puntuación, etc. Ahí fue cuando empecé a ver la ventaja. &lt;/p&gt;  &lt;p&gt;Tiempo después fue necesario reemplazar mi viejo equipo personal y al comprar una laptop en Tijuana, sin darme cuenta,&amp;#160; venia con teclado en español. Como ya estaba acostumbrado al teclado, por el trabajo en sitio, fue fácil usarlo. Una vez que deje de trabajar en sitio seguí trabajando fuera de la oficina, ahora desde mi casa, y seguía utilizando teclado en español. &lt;/p&gt;  &lt;p&gt;Después de un tiempo &lt;a href="http://www.developeando.com/2007/01/cosas-que-aprendi-en-coca-cola.html" target="_blank"&gt;cambié de trabajo&lt;/a&gt; y en esta empresa nos daban a cada uno una laptop para trabajar en ella. La laptop tenia el teclado en ingles, todo estaba bien hasta que necesitaba escribir acentos o ‘ñ’ es decir texto en español. En esa época fue cuando empecé a utilizar el teclado en &lt;a href="http://en.wikipedia.org/wiki/Keyboard_layout#US-International" target="_blank"&gt;EN International Sort&lt;/a&gt;. El cual ayuda con el texto en español pero no es tan cómodo como el teclado en español sobre todo al escribir comillas, lo cual puede ser común al momento de programar.&lt;/p&gt;  &lt;p&gt;En la actualidad cuando trabajo desde una computadora de escritorio utilizo un teclado en español (México) y cuando trabajo directamente desde la laptop lo utilizo en ingles (international sort) ya que mi laptop personal tiene teclado en ingles. Traté de comprarla en México para tener el teclado en español pero por el costo/beneficio la compré en US con teclado en ingles. &lt;/p&gt;  &lt;p&gt;En estos años usando teclado en español no he notado que afecte mi productividad al programar, han habido detalles cuando compañeros de trabajo ingresan a mi maquina de manera local o remota y no pueden teclear; pero fuera de eso no afecta y a la vez siento que me facilita la escritura de texto en español cuando es necesario.&lt;/p&gt;  &lt;p&gt;¡Ah olvidaba mencionar! Hace tiempo me toco usar teclado en &lt;a href="http://en.wikipedia.org/wiki/Keyboard_layout#Spanish_.28Spain.29.2C_aka_Spanish_.28International_sort.29" target="_blank"&gt;español internacional&lt;/a&gt; y ese teclado definitivamente no me gustó. Será quizás que no estoy acostumbrado; pero lo sentí muy incomodo.&lt;/p&gt;  &lt;p&gt;Nota: Esta entrada fue escrita desde un &lt;a href="http://en.wikipedia.org/wiki/Keyboard_layout#US-International" target="_blank"&gt;teclado en ingles (International sort)&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Post relacionado: &lt;a href="http://www.developeando.com/2011/12/software-en-espanol.html" target="_blank"&gt;Software en español&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-8476550519977213392?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/8476550519977213392/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=8476550519977213392' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8476550519977213392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8476550519977213392'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/12/teclado-en-espanol-latinoamerica.html' title='Teclado en español Latinoamérica'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-3516616211690168923</id><published>2011-12-29T22:13:00.001-08:00</published><updated>2011-12-30T11:22:15.615-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trabajo'/><title type='text'>Software en español</title><content type='html'>Aunque uso principalmente solo software en inglés, seguido tengo la tentación de usar software en español. Tanto en el sistema operativo como en las herramientas de desarrollo y de base de datos.&lt;br /&gt;Esto me pasa más cuando se trata de software administrativo, de entretenimiento o aplicaciones donde necesito escribir en español. En esos casos creo que sí tiene sentido usar aplicaciones e incluso el sistema operativo en español. Porque lo que realizo es en español y el programa (al estar en el mismo lenguaje) puede ofrecerme ayuda adicional. Por ejemplo prevenir faltas de ortografía, de gramática, etc.&lt;br /&gt;El problema viene al tratar de usar herramientas de desarrollo que no están en ingles, ya que &lt;a href="http://www.developeando.com/2011/06/el-ingles-es-parte-de-las-mejores.html" target="_blank"&gt;el desarrollo debe ser en inglés&lt;/a&gt; y si la herramienta de desarrollo esta en español es una desventaja. Tanto en los mensajes de error como en la terminología utilizada. Puede ser difícil encontrar información sobre términos técnicos en español o por lo menos encontrar información reciente.&lt;br /&gt;Hace tiempo instalé la versión en español de &lt;a href="http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-web-developer-express" target="_blank"&gt;visual web developer&lt;/a&gt; y se sentía raro usarlo, algunos mensajes arrojados por las excepciones no me eran familiares por estar en español. Pero fue algo divertido y quizás lo vuelva a intentar pero siento que podría haber problemas de compatibilidad con el resto del equipo.&lt;br /&gt;¿Es común usar software completamente en español? Por lo menos en frontera no lo he visto así; pero me gustaría saber como sería la experiencia. Quizás el próximo año me anime a hacer el experimento e instale todo en español para saber que se siente. Aunque presiento que no será posible tener las versiones más recientes.&lt;br /&gt;Post relacionado: &lt;a href="http://www.developeando.com/2011/12/teclado-en-espanol-latinoamerica.html" target="_blank"&gt;Teclado en Español Latinoamérica&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-3516616211690168923?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/3516616211690168923/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=3516616211690168923' title='4 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3516616211690168923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3516616211690168923'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/12/software-en-espanol.html' title='Software en español'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-7589838166815389157</id><published>2011-12-23T10:40:00.001-08:00</published><updated>2011-12-23T10:55:33.459-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Usando varios atributos en C#</title><content type='html'>Al trabajar en proyectos sobre ASP.NET MVC, al crear los modelos he estado usando &lt;a href="http://msdn.microsoft.com/es-es/library/system.componentmodel.dataannotations.aspx" target="_blank"&gt;Data Annotations&lt;/a&gt; las cuales consisten en agregar atributos a las propiedades de tu modelo para indicar algo de meta datos que pueden ser usados por la vista. Además de que al usar &lt;a href="http://blogs.msdn.com/b/adonet/archive/2011/09/28/ef-4-2-code-first-walkthrough.aspx" target="_blank"&gt;entity framework code first&lt;/a&gt; he necesitado en alguna ocasión usar atributos, aunque últimamente he optado por configurar eso en el mapping del DbContext. También en lo controladores hay necesidad de escribir algunos atributos para los &lt;a href="http://msdn.microsoft.com/es-mx/library/gg416513(v=VS.98).aspx" target="_blank"&gt;Action Filters&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;He visto que la forma más común para agregar más de un atributo a una clase, propiedad o método es escribiendo uno abajo del otro. Con lo que al declarar una propiedad que tiene&amp;nbsp;varios meta-datos se termine con varias líneas de código. O al definir una acción en un controlador donde necesitas que se ejecuten varios &lt;a href="http://msdn.microsoft.com/es-mx/library/gg416513(v=VS.98).aspx" target="_blank"&gt;action filters&lt;/a&gt; termines con varias líneas en la declaración del método, lo cual (en mi opinión) se ve igual que si se ejecutan las llamadas de los filtros dentro de los métodos.&lt;br /&gt;&lt;pre class="csharpcode"&gt;[&lt;span style="color: #6fa8dc;"&gt;Required&lt;/span&gt;]&lt;br /&gt;[&lt;span style="color: #6fa8dc;"&gt;DataType&lt;/span&gt;(&lt;span style="color: #76a5af;"&gt;DataType&lt;/span&gt;.Password)]&lt;br /&gt;[&lt;span style="color: #6fa8dc;"&gt;Display&lt;/span&gt;(Name = &lt;span class="str" style="color: #990000;"&gt;"Current password"&lt;/span&gt;)]&lt;br /&gt;&lt;span class="kwrd" style="color: blue;"&gt;public&lt;/span&gt; &lt;span class="kwrd" style="color: blue;"&gt;string&lt;/span&gt; OldPassword { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;br /&gt;En mi caso me ha gustado más el escribir los atributos uno a un lado del otro separados por coma dentro del mismo par de corchetes. Esto hace que sean menos líneas la declaración de un método, propiedad, etc. Y lo principal es que (para mi) se ve más claro. Es decir no es por ahorrarme líneas, las líneas son gratis, sino para quitar ruido en el código.&lt;br /&gt;&lt;pre class="csharpcode"&gt;[&lt;span style="color: #6fa8dc;"&gt;Required&lt;/span&gt;, &lt;span style="color: #6fa8dc;"&gt;DataType&lt;/span&gt;(&lt;span style="color: #6fa8dc;"&gt;DataType&lt;/span&gt;.Password), &lt;span style="color: #6fa8dc;"&gt;Display&lt;/span&gt;(Name = &lt;span class="str" style="color: #990000;"&gt;"Current password"&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;&lt;/span&gt; OldPassword { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;br /&gt;Como todo es cuestión de gustos y si todo el equipo decide usar uno abajo del otro me tendré que alinear; pero por lo pronto prefiero escribir uno después del otro.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-7589838166815389157?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/7589838166815389157/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=7589838166815389157' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/7589838166815389157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/7589838166815389157'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/12/usando-varios-atributos-en-c.html' title='Usando varios atributos en C#'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-3954640437528307473</id><published>2011-12-15T16:50:00.000-08:00</published><updated>2011-12-15T16:50:31.881-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TJNET'/><title type='text'>CoffeeCamp: El año en revisión</title><content type='html'>La &lt;a href="http://tjnet.org/" target="_blank"&gt;comunidad .Net de Tijuana&lt;/a&gt; organiza un CoffeeCamp el próximo Sábado 17 de diciembre de 2011 en el café &lt;span&gt;&lt;span class="Event_BriefDescription"&gt;Starbucks que esta frente a las torres. El tema es "El Año En Revisión". La idea es reunirnos y platicar de software mientras nos tomamos café (u otra cosa). En la &lt;a href="http://tjnet.org/Eventos/2046.aspx" target="_blank"&gt;página del evento&lt;/a&gt; pueden encontrar más información.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-w1cyaGGU79k/TuqVIuemqII/AAAAAAAAAYQ/L6Gu1c6tf8A/s1600/100_8282.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-w1cyaGGU79k/TuqVIuemqII/AAAAAAAAAYQ/L6Gu1c6tf8A/s320/100_8282.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-qDTA3_Ei1WU/TuqVKAa5kbI/AAAAAAAAAYY/v0SRCd0LwnU/s1600/100_8283.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-qDTA3_Ei1WU/TuqVKAa5kbI/AAAAAAAAAYY/v0SRCd0LwnU/s320/100_8283.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-N3EPGySCquI/TuqVqTnz9BI/AAAAAAAAAYg/K44sKS8Pvq8/s1600/100_8273.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-N3EPGySCquI/TuqVqTnz9BI/AAAAAAAAAYg/K44sKS8Pvq8/s320/100_8273.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;span class="Event_BriefDescription"&gt;Si eres desarrollador y estas en Tijuana el Sábado 17/12/11, esperamos verte por ahí.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-3954640437528307473?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/3954640437528307473/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=3954640437528307473' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3954640437528307473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3954640437528307473'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/12/coffeecamp-el-ano-en-revision.html' title='CoffeeCamp: El año en revisión'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-w1cyaGGU79k/TuqVIuemqII/AAAAAAAAAYQ/L6Gu1c6tf8A/s72-c/100_8282.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-4980343406305466514</id><published>2011-11-24T16:47:00.001-08:00</published><updated>2011-11-24T17:00:55.898-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Podcast'/><category scheme='http://www.blogger.com/atom/ns#' term='dev3cast'/><category scheme='http://www.blogger.com/atom/ns#' term='TJNET'/><title type='text'>Dev3Cast (Podcast) sobre FubuMVC</title><content type='html'>El pasado 12 de Noviembre participé en el podcast &lt;a href="http://dev3cast.com/"&gt;Dev3Cast&lt;/a&gt;. Donde junto con &lt;a href="http://msmvps.com/blogs/gflores/"&gt;Gabriel Flores&lt;/a&gt;&amp;nbsp;(&lt;a href="http://twitter.com/gabo"&gt;@gabo&lt;/a&gt;)&amp;nbsp; platicamos con&amp;nbsp;&lt;a href="http://wefollow.com/squidge"&gt;Francisco Ruiz&lt;/a&gt; (&lt;a href="http://twitter.com/#!/squidge"&gt;@squidge&lt;/a&gt;) sobre &lt;a href="http://mvc.fubu-project.org/"&gt;FubuMVC&lt;/a&gt;. El cual es un proyecto de código abierto para el desarrollo de aplicaciones web que corre sobre .Net (es una alternativa a ASP.NET MVC).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dev3cast.com/2011/11/12/fubumvc/"&gt;Escucha el episodio&lt;/a&gt;&amp;nbsp;y deja tus comentarios.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-4980343406305466514?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/4980343406305466514/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=4980343406305466514' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4980343406305466514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4980343406305466514'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/11/dev3cast-podcast-sobre-fubumvc.html' title='Dev3Cast (Podcast) sobre FubuMVC'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-8624294406629651850</id><published>2011-11-18T22:15:00.001-08:00</published><updated>2011-11-18T22:58:40.509-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trabajo'/><title type='text'>Mantenerse al día</title><content type='html'>Cuando empece a programar, la forma en que aprendía era principalmente a&amp;nbsp;través&amp;nbsp;de libros; pero sobre todo con la ayuda que me&amp;nbsp;proporcionaba&amp;nbsp;el entorno de desarrollo. Buscaba ejemplos que mostraran como&amp;nbsp;utilizar&amp;nbsp;cierta&amp;nbsp;función&amp;nbsp;o ejemplos de como lograr lo que&amp;nbsp;quería&amp;nbsp;hacer.&lt;br /&gt;&lt;br /&gt;Desde hace ya buen tiempo que no instalo la ayuda que viene con los entornos de desarrollo. Esto se debe, principalmente, a que es más&amp;nbsp;rápido&amp;nbsp;hacer una&amp;nbsp;búsqueda&amp;nbsp;en&amp;nbsp;Internet&amp;nbsp;sobre como funciona algo a buscar en la&amp;nbsp;documentación&amp;nbsp;que viene con los programas.&lt;br /&gt;&lt;br /&gt;Esto&amp;nbsp;también&amp;nbsp;ha ido pasando con la forma en que aprendo a usar o hacer cosas nuevas. Aun sigue siendo un buen recurso el tener un libro sobre&amp;nbsp;tecnología.&amp;nbsp;sobre todo los que son sobre principios&amp;nbsp;básicos; pero&amp;nbsp;también&amp;nbsp;es cierto que&amp;nbsp;los libros que tratan sobre&amp;nbsp;tecnologías&amp;nbsp;especificas&amp;nbsp;rápidamente&amp;nbsp;quedan obsoletos.&lt;br /&gt;&lt;br /&gt;Ahora para aprender sobre alguna&amp;nbsp;tecnología&amp;nbsp;(framework, lenguaje,&amp;nbsp;librería, etc.) me ayuda el buscar&amp;nbsp;información&amp;nbsp;en&amp;nbsp;Internet, generalmente es&amp;nbsp;fácil&amp;nbsp;encontrar la&amp;nbsp;teoría&amp;nbsp;sobre la cual esta fundada esa tecnología que quiero aprender. De&amp;nbsp;ahí&amp;nbsp;trato de buscar screencasts. En lo personal me ayuda mucho ver un screencast donde se vea la&amp;nbsp;aplicación&amp;nbsp;de esa&amp;nbsp;tecnología. Para ver lo especifico y así tratar de aplicarlo en una practica.&lt;br /&gt;&lt;br /&gt;Algo que me ayuda,&amp;nbsp;también, a estar enterado de que es lo que se usa fuera de mi trabajo. Es el escuchar podcasts con regularidad. Aunque no todo lo que escucho lo trato de poner en practica, aun así me sirve para estar enterado de las opciones que hay disponibles. Y así cuando se presente una oportunidad, por lo menos sabré que preguntas hacer ya que conoceré un poco del tema. El leer blogs&amp;nbsp;también&amp;nbsp;ayuda -es muy incomodo tener&amp;nbsp;discusiones&amp;nbsp;con&amp;nbsp;algún&amp;nbsp;desarrollador por temas que hace años la comunidad ya&amp;nbsp;resolvió-. Ademas de asistir a las reuniones de los grupos de usuarios locales y a eventos donde se pueda hablar en persona con quienes usan esa&amp;nbsp;tecnología&amp;nbsp;que quiero conocer.&lt;br /&gt;&lt;br /&gt;Otra cosa que me ayuda es tratar de mantener este blog con contenido actual, eso me motiva a presentar buen contenido y por lo tanto a buscar aprender ese contenido que trataré de explicar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-8624294406629651850?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/8624294406629651850/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=8624294406629651850' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8624294406629651850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8624294406629651850'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/11/mantenerse-al-dia.html' title='Mantenerse al día'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-6450154185793443812</id><published>2011-10-29T21:58:00.002-07:00</published><updated>2011-10-29T22:00:04.710-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Podcast'/><category scheme='http://www.blogger.com/atom/ns#' term='dev3cast'/><title type='text'>Dev3Cast sobre Build</title><content type='html'>El pasado 5 de octubre participé en un &lt;a href="http://www.dev3cast.com/2011/10/05/build/"&gt;episodio de dev3cast&lt;/a&gt; (podcast) donde hablamos sobre lo que se presento en el evento &lt;a href="http://www.buildwindows.com/"&gt;build&lt;/a&gt; de Microsoft, en el cual se mostró lo que viene en la siguiente versión de windows y Visual Studio. Tuvimos como invitado especial a &lt;a href="http://www.devexpress.com/seth"&gt;Seth Juarez&lt;/a&gt;, quien asistió al evento como parte de &lt;a href="http://www.devexpress.com/"&gt;devexpress&lt;/a&gt; y pudo hacer varias entrevistas estando allá. También participamos en la conversación &lt;a href="http://msmvps.com/blogs/gflores"&gt;Gabriel Flores&lt;/a&gt;, &lt;a href="http://www.developeandocsharp.net/"&gt;Samuel Arellano&lt;/a&gt; y &lt;a href="http://twitter.com/mhcornejo"&gt;yo&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-6450154185793443812?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/6450154185793443812/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=6450154185793443812' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6450154185793443812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6450154185793443812'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/10/dev3cast-sobre-build.html' title='Dev3Cast sobre Build'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-4065023721842258005</id><published>2011-10-27T15:52:00.001-07:00</published><updated>2011-10-29T22:00:27.636-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Podcast'/><category scheme='http://www.blogger.com/atom/ns#' term='dev3cast'/><title type='text'>Dev3Cast sobre ASP.NET vNext</title><content type='html'>El día de ayer participe en la grabación de un &lt;a href="http://www.dev3cast.com/2011/10/26/aspnet-vnext/"&gt;episodio &lt;/a&gt;del podcast de la&lt;a href="http://tjnet.org/"&gt; comunidad de usuarios .net en Tijuana&lt;/a&gt;, &lt;a href="http://dev3cast.com/"&gt;dev3cast&lt;/a&gt;. Donde hablé, junto con &lt;a href="http://msmvps.com/blogs/gflores"&gt;Gabriel Flores&lt;/a&gt; y &lt;a href="http://www.developeandocsharp.net/"&gt;Samuel Arellano&lt;/a&gt;, sobre algunas de la características que vienen en la próxima versión de ASP.NET.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-4065023721842258005?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/4065023721842258005/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=4065023721842258005' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4065023721842258005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4065023721842258005'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/10/dev3cast-sobre-aspnet-vnext.html' title='Dev3Cast sobre ASP.NET vNext'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-546734921173070015</id><published>2011-10-03T21:30:00.001-07:00</published><updated>2011-10-03T21:31:55.656-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='RubyOnRails'/><category scheme='http://www.blogger.com/atom/ns#' term='magmarails'/><title type='text'>Rumbo a MagmaRails (parte 4)</title><content type='html'>&lt;p&gt;En la parte &lt;a href="http://www.developeando.com/2011/09/rumbo-magmarails-parte-3.html" target="_blank"&gt;anterior&lt;/a&gt; de la serie, generé el modelo y controlador para los invitados, además de que modifiqué el archivo routes.rb para colocar a los invitados como recursos dentro de otros recursos:&lt;/p&gt; &lt;pre&gt;resources :weddings do      &lt;br /&gt;  resources :guests  &lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Esto hace que pueda tener una ruta como &lt;em&gt;/weddings/{wedding_id}/guests/&lt;/em&gt; para mostrar la lista de invitados según la boda que se pase a través del URL.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Para leer el valor de la boda dentro del controlador utilizamos la variable &lt;em&gt;params &lt;/em&gt;la cual es como un diccionario. Así dentro de nuestro controlador de invitados podemos obtener el valor del ID de la boda de la siguiente forma:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;def index    &lt;br /&gt;  wedding_id = params[:wedding_id]&lt;br /&gt;  @wedding = Wedding.find wedding_id&lt;br /&gt;  @guests = @wedding.guests.all&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;La función del controlador es la de asignar valores a las variables que necesita la vista para mostrarse al usuario. En este caso estoy obteniendo el valor de wedding_id que viene dentro de los parámetros y lo estoy guardando en la variable &lt;em&gt;wedding_id.&lt;/em&gt;&amp;#160; después uso ese valor para obtener el objeto completo de la boda (usando el método de la clase &lt;em&gt;Wedding&lt;/em&gt;). También obtengo la lista de invitados a través del objeto boda.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Una vez que asignamos los valores a variables, estos pueden ser usados por la vista para mostrarse al usuario. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;ya he grabado antes &lt;a title="Screencasts sobre rails" href="http://www.developeando.com/search/label/NetBeans" target="_blank"&gt;screencasts&lt;/a&gt; donde se muestra algo de esto. En aquella ocasión usaba netbeans y una versión anterior de rails, pero los mismos conceptos aplican. Pueden verse &lt;a href="http://www.developeando.com/search/label/NetBeans" target="_blank"&gt;aquí&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-546734921173070015?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/546734921173070015/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=546734921173070015' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/546734921173070015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/546734921173070015'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/10/rumbo-magmarails-parte-4.html' title='Rumbo a MagmaRails (parte 4)'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2047830241165768001</id><published>2011-09-12T20:55:00.001-07:00</published><updated>2011-09-12T20:55:20.809-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='RubyOnRails'/><category scheme='http://www.blogger.com/atom/ns#' term='magmarails'/><title type='text'>Rumbo a MagmaRails (Parte 3)</title><content type='html'>&lt;p&gt;Sigo preparándome para asistir a &lt;a href="http://magmarails.com" target="_blank"&gt;MagmaRails&lt;/a&gt;, en este &lt;a href="http://screencast.com/t/62Nj0KwixEm" target="_blank"&gt;video&lt;/a&gt; genero el modelo y controlador para los invitados:&lt;/p&gt;  &lt;p&gt;&lt;object id="scPlayer" class="embeddedObject" width="600" height="400" type="application/x-shockwave-flash" data="http://content.screencast.com/users/mariohcornejo/folders/Jing/media/0804326c-ac74-4632-8f3e-11577d917055/jingswfplayer.swf" &gt;  	&lt;param name="movie" value="http://content.screencast.com/users/mariohcornejo/folders/Jing/media/0804326c-ac74-4632-8f3e-11577d917055/jingswfplayer.swf" /&gt; 	&lt;param name="quality" value="high" /&gt; 	&lt;param name="bgcolor" value="#FFFFFF" /&gt; 	&lt;param name="flashVars" value="containerwidth=600&amp;amp;containerheight=400&amp;amp;thumb=http://content.screencast.com/users/mariohcornejo/folders/Jing/media/0804326c-ac74-4632-8f3e-11577d917055/FirstFrame.jpg&amp;amp;content=http://content.screencast.com/users/mariohcornejo/folders/Jing/media/0804326c-ac74-4632-8f3e-11577d917055/rumboMagmarails_guests.swf&amp;amp;blurover=false" /&gt; 	&lt;param name="allowFullScreen" value="true" /&gt; 	&lt;param name="scale" value="showall" /&gt; 	&lt;param name="allowScriptAccess" value="always" /&gt; 	&lt;param name="base" value="http://content.screencast.com/users/mariohcornejo/folders/Jing/media/0804326c-ac74-4632-8f3e-11577d917055/" /&gt; &lt;/object&gt;&lt;/p&gt;  &lt;p&gt;Post relacionados:   &lt;br /&gt;&lt;a href="http://www.developeando.com/2011/08/rumbo-magmarails.html" target="_blank"&gt;Parte 1&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://www.developeando.com/2011/09/rumbo-magmarails-parte-2.html" target="_blank"&gt;Parte 2&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2047830241165768001?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2047830241165768001/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2047830241165768001' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2047830241165768001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2047830241165768001'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/09/rumbo-magmarails-parte-3.html' title='Rumbo a MagmaRails (Parte 3)'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-8739591508861864173</id><published>2011-09-01T21:27:00.001-07:00</published><updated>2011-09-12T20:57:50.528-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='RubyOnRails'/><category scheme='http://www.blogger.com/atom/ns#' term='magmarails'/><title type='text'>Rumbo a MagmaRails (parte 2)</title><content type='html'>&lt;p&gt;Siguiendo con la serie para prepararnos para &lt;a href="http://magmarails.com" target="_blank"&gt;MagmaRails&lt;/a&gt;. En esta ocasión trato de explicar en 5 minutos lo que se generó en &lt;a href="http://www.developeando.com/2011/08/rumbo-magmarails.html" target="_blank"&gt;la primera parte&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Aquí el &lt;a href="http://screencast.com/t/6nvfTVCu" target="_blank"&gt;video&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;object id="scPlayer" class="embeddedObject" width="600" height="400" type="application/x-shockwave-flash" data="http://content.screencast.com/users/mariohcornejo/folders/Jing/media/ec61b25c-525b-494a-a44e-fdc2af626386/jingswfplayer.swf" &gt;  	&lt;param name="movie" value="http://content.screencast.com/users/mariohcornejo/folders/Jing/media/ec61b25c-525b-494a-a44e-fdc2af626386/jingswfplayer.swf" /&gt; 	&lt;param name="quality" value="high" /&gt; 	&lt;param name="bgcolor" value="#FFFFFF" /&gt; 	&lt;param name="flashVars" value="containerwidth=600&amp;amp;containerheight=400&amp;amp;thumb=http://content.screencast.com/users/mariohcornejo/folders/Jing/media/ec61b25c-525b-494a-a44e-fdc2af626386/FirstFrame.jpg&amp;amp;content=http://content.screencast.com/users/mariohcornejo/folders/Jing/media/ec61b25c-525b-494a-a44e-fdc2af626386/2011-09-01_2109.swf&amp;amp;blurover=false" /&gt; 	&lt;param name="allowFullScreen" value="true" /&gt; 	&lt;param name="scale" value="showall" /&gt; 	&lt;param name="allowScriptAccess" value="always" /&gt; 	&lt;param name="base" value="http://content.screencast.com/users/mariohcornejo/folders/Jing/media/ec61b25c-525b-494a-a44e-fdc2af626386/" /&gt; &lt;/object&gt;&lt;/p&gt; Entradas relacionadas:   &lt;br /&gt;- &lt;a href="http://www.developeando.com/2011/08/rumbo-magmarails.html" target="_blank"&gt;Rumbo a MagmaRails (Parte 1)&lt;/a&gt;  &lt;br /&gt;- &lt;a href="http://www.developeando.com/2011/09/rumbo-magmarails-parte-3.html" target="_blank"&gt;Rumbo a MagmaRails (Parte 3)&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-8739591508861864173?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/8739591508861864173/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=8739591508861864173' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8739591508861864173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8739591508861864173'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/09/rumbo-magmarails-parte-2.html' title='Rumbo a MagmaRails (parte 2)'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2727758025984653486</id><published>2011-08-30T21:59:00.001-07:00</published><updated>2011-09-12T20:56:48.243-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='RubyOnRails'/><category scheme='http://www.blogger.com/atom/ns#' term='magmarails'/><title type='text'>Rumbo a MagmaRails</title><content type='html'>&lt;p&gt;El próximo 12 de octubre se realizará en Manzanillo la conferencia &lt;a href="http://magmarails.com"&gt;MagmaRails&lt;/a&gt; a la cual pretendo (junto con mi esposa) asistir. Nosotros trabajamos principalmente con tecnología .Net así que para practicar un poco de rails inicié un proyecto y estoy grabando algunas partes en screencasts de 5 minutos.&amp;#160; &lt;a href="http://screencast.com/t/ZeJKMdjtD"&gt;Aquí&lt;/a&gt; el primero:&lt;/p&gt;  &lt;p&gt;&lt;object id="scPlayer" class="embeddedObject" width="600" height="400" type="application/x-shockwave-flash" data="http://content.screencast.com/users/mariohcornejo/folders/Jing/media/5b3d3614-5f5e-44a7-8e2a-432161c09cfc/jingswfplayer.swf" &gt;  	&lt;param name="movie" value="http://content.screencast.com/users/mariohcornejo/folders/Jing/media/5b3d3614-5f5e-44a7-8e2a-432161c09cfc/jingswfplayer.swf" /&gt; 	&lt;param name="quality" value="high" /&gt; 	&lt;param name="bgcolor" value="#FFFFFF" /&gt; 	&lt;param name="flashVars" value="containerwidth=600&amp;amp;containerheight=400&amp;amp;thumb=http://content.screencast.com/users/mariohcornejo/folders/Jing/media/5b3d3614-5f5e-44a7-8e2a-432161c09cfc/FirstFrame.jpg&amp;amp;content=http://content.screencast.com/users/mariohcornejo/folders/Jing/media/5b3d3614-5f5e-44a7-8e2a-432161c09cfc/pre_magma_rails.swf&amp;amp;blurover=false" /&gt; 	&lt;param name="allowFullScreen" value="true" /&gt; 	&lt;param name="scale" value="showall" /&gt; 	&lt;param name="allowScriptAccess" value="always" /&gt; 	&lt;param name="base" value="http://content.screencast.com/users/mariohcornejo/folders/Jing/media/5b3d3614-5f5e-44a7-8e2a-432161c09cfc/" /&gt; &lt;/object&gt;&lt;/p&gt;  &lt;p&gt;Entradas relacionadas:    &lt;br /&gt;- &lt;a href="http://www.developeando.com/2011/09/rumbo-magmarails-parte-2.html" target="_blank"&gt;Rumbo a MagmaRails (Parte 2)&lt;/a&gt;    &lt;br /&gt;- &lt;a href="http://www.developeando.com/2011/09/rumbo-magmarails-parte-3.html" target="_blank"&gt;Rumbo a MagmaRails (Parte 3)&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2727758025984653486?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2727758025984653486/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2727758025984653486' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2727758025984653486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2727758025984653486'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/08/rumbo-magmarails.html' title='Rumbo a MagmaRails'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2021971443334710356</id><published>2011-06-29T17:31:00.001-07:00</published><updated>2011-06-29T17:40:18.485-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TJNET'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='razor'/><title type='text'>Reunión 44 de Tijuana .Net Sobre Razor</title><content type='html'>&lt;p&gt;&lt;a href="http://lh3.ggpht.com/-54QoDyu-OkU/TgvDv69oIJI/AAAAAAAAASE/KSxlxe8qvS4/s1600-h/Razor%25255B3%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Razor" border="0" alt="Razor" src="http://lh3.ggpht.com/-ogOsZ2uLmck/TgvDwzXo6WI/AAAAAAAAASI/YOfeyR55d88/Razor_thumb.jpg?imgmax=800" width="204" height="166" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;El día de hoy estaré presentando en la &lt;a href="http://tjnet.org/Eventos/2022.aspx"&gt;reunión 44&lt;/a&gt; de la &lt;a href="http://tjnet.org"&gt;comunidad&lt;/a&gt; el tema de Razor. Hablaremos de la sintaxis de razor usando &lt;a href="http://www.microsoft.com/web/webmatrix/"&gt;WebMatrix&lt;/a&gt; en &lt;a href="http://www.asp.net/web-pages"&gt;webpages&lt;/a&gt; y después un ejemplo de un blog usando razor en asp.net mvc en Visual Studio.&lt;/p&gt;  &lt;p&gt;Los temas serán:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Code blocks &lt;/li&gt;    &lt;li&gt;Syntax, encoding &lt;/li&gt;    &lt;li&gt;Code expresions &lt;/li&gt;    &lt;li&gt;Html Helpers en razor &lt;/li&gt;    &lt;li&gt;Layout &lt;/li&gt;    &lt;li&gt;Sections &lt;/li&gt;    &lt;li&gt;Html helper en C# &lt;/li&gt;    &lt;li&gt;EditorTemplates &lt;/li&gt;    &lt;li&gt;Partial Views &lt;/li&gt;    &lt;li&gt;Html.Action &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Esperamos grabar la presentación y mostrarla aquí y en la página del evento.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2021971443334710356?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2021971443334710356/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2021971443334710356' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2021971443334710356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2021971443334710356'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/06/reunion-44-de-tijuana-net-sobre-razor.html' title='Reunión 44 de Tijuana .Net Sobre Razor'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-ogOsZ2uLmck/TgvDwzXo6WI/AAAAAAAAASI/YOfeyR55d88/s72-c/Razor_thumb.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-4408177621095319440</id><published>2011-06-17T22:40:00.001-07:00</published><updated>2011-06-18T22:43:16.004-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Refactorización'/><category scheme='http://www.blogger.com/atom/ns#' term='Trabajo'/><title type='text'>Adicción a la Refactorización</title><content type='html'>&lt;p&gt;Siempre que trabajo en una nueva característica, para algún proyecto, modifico el código antes de entregarlo. Tratando de hacerlo más compacto y/o fácil de leer. Esto con la intención de mejorar la calidad del código.&lt;/p&gt;  &lt;p&gt;También cuando necesito modificar cierta funcionalidad existente, cambio el código antes de implementar los cambios. Con la intención de entender mejor la funcionalidad actual y así dejar todo listo para realizar los cambios que se requieren implementar. Una vez hechos los cambios vuelvo a buscar áreas donde haya oportunidad de refactorizar…hasta ahí creo que todo va bien. El problema viene cuando se convierte en una especie de adicción. &lt;/p&gt;  &lt;p&gt;Hay ocasiones que al trabajar en alguna característica determinada me encuentro con algún trozo de código “malo” que no esta relacionado con lo que estoy trabajando y aun así siento la necesidad de modificarlo. A veces logro aguantarme las ganas; pero otras veces simplemente no puedo evitarlo. También me pasa cuando algún compañero de trabajo me pregunta&amp;#160; algo especifico y al mostrarme el código quiero empezar a modificarlo, cuando ese no es el punto de la pregunta que me hicieron. Aunque estoy tratando de que el código sea mejor, puede convertirse en un problema. &lt;/p&gt;  &lt;p&gt;A veces no se si lo hago por el proyecto o lo hago por mi. El código “malo” puede ser mucho, por lo tanto requiere algo de tiempo. Aunque hay herramientas que ayudan con la refactorización (ya sea como parte del IDE o como plugins), aun así es tiempo que le estoy quitando a tareas que el cliente espera y que están pendientes por realizar.&lt;/p&gt;  &lt;p&gt;Estoy convencido de que La refactorización constante ayuda a la calidad del código, mantiene activo al proyecto, previene en cierta medida que el proyecto se vuelva legacy. Pero también debo aceptar que existe código que se puede mejorar y que esta bien (si funciona) dejarlo así como esta. Aunque sea difícil de vencer la tentación de mejorarlo. Es importante enfocarse en las tareas que le dan valor al usuario y en ocasiones la refactorización no da ese valor. &lt;/p&gt;  &lt;p&gt;Como en todo lo demás: “Es bueno el uso; pero no el abuso”.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-4408177621095319440?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/4408177621095319440/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=4408177621095319440' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4408177621095319440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4408177621095319440'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/06/adiccion-la-refactorizacion.html' title='Adicción a la Refactorización'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-5074865919977193709</id><published>2011-06-15T12:22:00.001-07:00</published><updated>2011-06-15T12:31:07.339-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trabajo'/><title type='text'>Motivación diaria</title><content type='html'>&lt;p&gt;Hay días en los que siento que soy productivo y tengo muchas ganas de programar. En cambio hay otros en los que simplemente no tengo ganas, estoy frente a la computadora, pero no logro avanzar en las tareas pendientes. Tratando de encontrar cuales son los factores que influyen para estar motivado y ser productivo, identifique los siguientes:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Conocer el dominio del problema&lt;/strong&gt;: Cuando ya se lo que tengo que hacer es más rápido ponerme a hacerlo. Cuando no conozco el beneficio o la razón de una característica del sistema donde estoy trabajando, o peor cuando no se exactamente que es lo que se supone que debe de hacer, mi productividad baja. Cuando se lo que se requiere, simplemente lo hago.     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Comunicación constante&lt;/strong&gt;: Esto va ligado al primer punto, para conocer el dominio del problema es necesaria una comunicación constante con el cliente. Cuando tengo dudas y el cliente tarda mucho en contestarlas o simplemente no lo hace, en algunos de esos casos simplemente no puedo avanzar, me desmotiva y se me quitan las ganas de trabajar en eso. También la comunicación entre los miembros del equipo me ayuda a mantenerme enfocado en lo que se quiere lograr, no me aburro ni busco algo con que entretenerme en el internet. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Tareas cortas y bien definidas&lt;/strong&gt;: Tener bien definidas las acciones concretas a realizar me permite concentrarme en esa acción, evitando la parálisis por análisis. Que las tareas sean cortas me ayuda a poder terminarlas en poco tiempo. Dándome una sensación de avance, la cual, me motiva a seguir avanzando en el proyecto.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Café&lt;/strong&gt;: Hay días que lo más difícil es empezar. Una vez que inicio con las tareas, el resto no es tan difícil. Para iniciar con ganas un café por la mañana ha sido muy efectivo.&amp;#160; Hay ocasiones (generalmente después de comer) que no tengo ganas de programar y lo único que pienso es en la hora de la salida. Para esos casos una bebida energética me “vuelve a la vida”, después ni cuenta me doy cuando ya es hora de irme.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Evitar interrupciones&lt;/strong&gt;: Una vez que ya inicié a programar es fácil enracharse. El problema con las interrupciones es que me quitan esa viada que llevaba y necesito volver a empezar (que es lo más difícil). Las interrupciones pueden ser tanto internas (por mi mismo) o externas (alguien más me interrumpe). Para las externas no hay mucho que pueda hacer; pero para las internas he notado que el escuchar &lt;strong&gt;música&lt;/strong&gt; me ayuda a concentrarme en lo que estoy, sin tratar de ver que dice la gente en las redes sociales o ver alguna foto graciosa.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Evitar estrés&lt;/strong&gt;: Una mente tranquila produce más, que una mente casada o frustrada. Algunas veces el trabajo no es como quisiera, ya sea por decisiones de los managers, trabajar con sistemas legacy, “clientes especiales”, etcétera. Aunque me quejo seguido por cosas así, trato de que no me afecte al momento escribir código. Y si me pongo a pensar en esas cosas mejor me voy a caminar un rato, para que se me pase o para hablarlo con alguien más. Para evitar el estrés también ayuda estar bien con la familia, dormir bien… o no dormir &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Guiño" src="http://lh4.ggpht.com/--jklTq0lpL4/TfkGf66rGWI/AAAAAAAAAR8/UmhlxCKYaPw/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" /&gt;.&lt;/p&gt;  &lt;p&gt;Bueno… estos son algunos de los factores que he notado ayudan a mantenerme contento trabajando, motivado y productivo.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-5074865919977193709?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/5074865919977193709/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=5074865919977193709' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5074865919977193709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5074865919977193709'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/06/motivacion-diaria.html' title='Motivación diaria'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/--jklTq0lpL4/TfkGf66rGWI/AAAAAAAAAR8/UmhlxCKYaPw/s72-c/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-1152346516758743857</id><published>2011-06-02T21:06:00.002-07:00</published><updated>2011-06-03T14:59:29.583-07:00</updated><title type='text'>El ingles es parte de las mejores practicas</title><content type='html'>Hace algunos años&amp;nbsp;leí&amp;nbsp;un comentario que no me gustó mucho.&amp;nbsp;Decía&amp;nbsp;algo como que todos los buenos desarrolladores&amp;nbsp;sabían&amp;nbsp;ingles. No me gustó, creo principalmente, porque mi primer idioma no es el ingles. Ademas conozco a personas que no hablan ingles y que son muy&amp;nbsp;capaces de desarrollar. Me&amp;nbsp;pareció&amp;nbsp;un poco arrogante el comentario. Sin embargo en ese momento recuerdo que no pude pensar en&amp;nbsp;algún&amp;nbsp;programador que no hablara ingles; pero pensé que se&amp;nbsp;debía&amp;nbsp;a que vivo en la frontera con los Estados Unidos (Tijuana) y&amp;nbsp;aquí&amp;nbsp;la&amp;nbsp;mayoría&amp;nbsp;habla (o por lo menos entiende) ingles.&lt;br /&gt;&lt;br /&gt;Ahora,&amp;nbsp;después&amp;nbsp;de ya&amp;nbsp;algún&amp;nbsp;tiempo, me ha tocado conocer a colegas desarrolladores que no dominan el ingles y he visto como sus opciones para buscar&amp;nbsp;información,&amp;nbsp;sobre cualquier tema&amp;nbsp;técnico, se ve limitada comparada con la cantidad de&amp;nbsp;información&amp;nbsp;que se puede encontrar en ingles. Esto es más notorio cuando se trata de&amp;nbsp;tecnología o&amp;nbsp;técnicas&amp;nbsp;nuevas (tendencias).&lt;br /&gt;&lt;br /&gt;La&amp;nbsp;mayoría&amp;nbsp;de la&amp;nbsp;información&amp;nbsp;técnica&amp;nbsp;es generada en ingles, incluso cuando para quien la genera el ingles no es su primera lengua.&amp;nbsp;Esto puede causar que por la falta de información, sobre algo nuevo por ejemplo, se pierda competitividad frente a otros desarrolladores que sí dominan el ingles y pueden usar la información a su favor (más en estos tiempos donde google es una herramienta muy usada en el desarrollo).&lt;br /&gt;&lt;br /&gt;El saber ingles ayuda a tener más opciones para resolver problemas y eso (en mi&amp;nbsp;opinión) te hace un mejor desarrollador. Ademas los lenguajes de&amp;nbsp;programación&amp;nbsp;y las APIs estan en ingles, conociendo el ingles se puede leer, escribir... por lo tanto entender y mantener el código con mayor facilidad. &lt;br /&gt;&lt;br /&gt;Hay varios esfuerzos para tener&amp;nbsp;información&amp;nbsp;disponible en español, ya que es nuestro idioma (creo que este blog es parte de ese esfuerzo). Aun así, si se desea conocer las mejores practicas y como aplicarlas, el ingles debe de estar en esa lista.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-1152346516758743857?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/1152346516758743857/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=1152346516758743857' title='5 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1152346516758743857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1152346516758743857'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/06/el-ingles-es-parte-de-las-mejores.html' title='El ingles es parte de las mejores practicas'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-1277079764606305711</id><published>2011-05-06T22:19:00.001-07:00</published><updated>2011-05-06T22:19:17.146-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Podcast'/><category scheme='http://www.blogger.com/atom/ns#' term='dev3cast'/><category scheme='http://www.blogger.com/atom/ns#' term='TJNET'/><title type='text'>Dev3Cast Sobre Documentación Técnica</title><content type='html'>El pasado cinco de mayo participé en un episodio de dev3cast junto con Eber Irigoyen, Haarón González, Samuel  Arellano y Gabriel Flores. Donde hablamos sobre la documentación técnica en proyectos de software.&lt;br /&gt;&lt;br /&gt;Pueden descargar el &lt;a href="http://www.dev3cast.com/2011/05/05/documentacion-tecnica/"&gt;episodio&lt;/a&gt; y comentar en el sitio de &lt;a href="http://www.dev3cast.com/"&gt;dev3cast&lt;/a&gt; para que todos quienes descarguen el podcast puedan leer sus opiniones.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-1277079764606305711?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/1277079764606305711/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=1277079764606305711' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1277079764606305711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1277079764606305711'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/05/dev3cast-sobre-documentacion-tecnica.html' title='Dev3Cast Sobre Documentación Técnica'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-5554712339081655073</id><published>2011-03-21T22:18:00.001-07:00</published><updated>2011-03-22T22:48:43.822-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trabajo'/><title type='text'>Aplicar lo nuevo lleva su tiempo</title><content type='html'>&lt;p&gt;Uno de los “problemas” que he encontrado al querer aplicar técnicas, usar librerías, frameworks, lenguajes, etcétera. De los que he leído e incluso usado en algún &lt;a href="http://www.allwords.com/word-pet+project.html" target="_blank"&gt;pet Project&lt;/a&gt;. Es que al momento de querer aplicarlo en algún proyecto real, este tienen fechas de entrega a muy corto plazo y por lo tanto lo más “seguro”, para cumplir con esas fechas de entrega, es haciéndolo utilizando lo ya conocido y probado en proyectos anteriores.&lt;/p&gt;  &lt;p&gt;No es común que el cliente nos pida alguna aplicación y nos de el tiempo necesario para aprender la tecnología a usar. Primero porque desea &lt;a href="http://www.developeando.com/2011/02/desarrollo-web-arrastrando-y-soltando.html" target="_blank"&gt;el sistema lo más rápido posible&lt;/a&gt; y segundo porque no quiere cubrir el costo del tiempo invertido en aprender lo nuevo. Cuando al final el recibe el mismo sistema, no importando la tecnología o técnicas usadas en el desarrollo.&lt;/p&gt;  &lt;p&gt;Pude ser que esta necesidad sea mas del desarrollador, ya que es él el que trabaja directamente con la tecnología (ya sea framework,lenguaje de programación, etc).&lt;/p&gt;  &lt;p&gt;Para poder aplicar/implementar algo nuevo en un proyecto real requiere de un esfuerzo adicional al que se necesitaría para aplicar lo que ya se conoce. Todo, por fácil que sea, tiene su curva de aprendizaje, sus ventajas y sus desventajas y debes de haberte encontrado con algunas de ellas antes de poder usarlo en producción, para que así sepas como resolver lo posibles problemas que se presenten.&lt;/p&gt;  &lt;p&gt;Pero entonces. ¿Como puedo aplicar o usar lo nuevo en los proyectos de mi trabajo, si nunca tengo el tiempo necesario? Algo que he tenido que hacer al querer aplicar algo nuevo en proyectos del trabajo es primero practicar por fuera en proyectos personales (a.k.a. pet projects) la tecnología/técnica que me interesa y en una oportunidad que se presente proponer el uso de tal tecnología o técnica. Esta propuesta procuro hacerla mostrando algo ya funcionando (un demo funcional), para convencer de las bondades que tiene utilizar lo nuevo.&lt;/p&gt;  &lt;p&gt;Esto requiere dedicarle tiempo extra al trabajo, porque lo aprendido en pet projects lleva su tiempo aplicarlo en proyectos reales. Puede incluso llegar a ser frustrante tardar en realizar algo sencillo que usando lo que ya conocemos lo haríamos en minutos; pero a la larga es aun más frustrante (por lo menos para mi) el trabajar con técnicas/tecnologías viejas, con las que no puedo lograr lo que se que es posible realizar con algo nuevo.&lt;/p&gt;  &lt;p&gt;De no dedicarle tiempo por mi cuenta a practicar lo que quiero usar, la decisión de usar algo diferente correría totalmente a cargo de alguien más, ya sea el cliente, jefe o algún programador más que hiciera la sugerencia. Para algunos eso no es problema, esperar que a el jefe/cliente se le ocurra intentar algo nuevo (a veces hasta que ya no es tan nuevo, incluso ya viejo); pero para mi &lt;a href="http://www.developeando.com/2011/03/al-desarrollador-le-gusta-desarrollar.html" target="_blank"&gt;conocer y no aplicarlo no es divertido&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Entonces: Si quiero usar algo nuevo tengo que proponerlo, lo mejor seria hacerlo mostrando avances donde puedan verse las ventajas. Esto requiere algunas veces dedicar algo de mi propio &lt;a href="http://www.dev3cast.com/2010/06/15/nuevas-tecnologias-%C2%BFa-que-horas/" target="_blank"&gt;tiempo para aprender las nuevas tecnologías&lt;/a&gt; y así poder convencer a los clientes/jefes que estamos listos para usar la tecnología/técnica nueva, porque el cliente no quiere pagar la curva de aprendizaje.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-5554712339081655073?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/5554712339081655073/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=5554712339081655073' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5554712339081655073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5554712339081655073'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/03/aplicar-lo-nuevo-lleva-su-tiempo.html' title='Aplicar lo nuevo lleva su tiempo'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-7785998604658543034</id><published>2011-03-14T22:05:00.002-07:00</published><updated>2011-03-15T11:15:28.541-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trabajo'/><title type='text'>La practica hace al maestro</title><content type='html'>&lt;p&gt;Hace unos días tuve la oportunidad de dar una capacitación (en el .Net Framework) a unos compañeros de trabajo que acaban de egresar de la universidad y que aun no tienen experiencia laboral. Algo común entre ellos era la falta de practica al momento de empezar a escribir código. Podían entender fácilmente el ejemplo escrito por mi, pero no les era igual de fácil escribir código propio. &lt;/p&gt;  &lt;p&gt;Me di cuenta que algunos tomaban varias notas en papel sobre lo que íbamos haciendo, en lugar de ponerse a practicar. Esto me hizo pensar que el aprender (y mejorar) a programar debe de hacerse de la misma forma en la que se aprenden las matemáticas. No basta con saber los procedimientos para resolver un problema, es necesario practicar las operaciones con varios ejercicios para poder dominar el tema (y resolver los problemas mas rápido y fácil).&lt;/p&gt;  &lt;p&gt;Cuando aprendemos a sumar, restar, multiplicar, dividir, etcétera. La parte de tomar notas es muy poca, la mayor parte del aprendizaje se da al practicar. Lo mismo pasa con la ortografía, no es solo conociendo las reglas, es con la practica constante como aprendemos a escribir mejor y cometer menos faltas de ortografía (como reconocer las palabras que llevan acento).&lt;/p&gt;  &lt;p&gt;También se podría comparar con el aprender un segundo idioma, llega un momento en que puedes entenderlo casi perfectamente pero para poder hablarlo correctamente se necesita de practica, equivocarte constantemente hasta que puedas darte cuenta que algo no suena bien y busques una mejor forma de expresarlo. Y si dejas de practícar puede ser que algunas palabras se te olviden aunque no tuvieras ningún problema en entenderla si alguien mas la dice.&lt;/p&gt;  &lt;p&gt;Considero para que un desarrollador profesional pueda seguir superándose es importante leer, ya sea blog posts, artículos, código de algún proyecto de código abierto, screencasts, podcasts, en fin… &lt;a href="http://www.dev3cast.com/2011/02/08/blogs-para-y-de-tecnologicos/" target="_blank"&gt;consumir y producir contenido técnico&lt;/a&gt;. Pero algo que ayuda mucho a ser un mejor desarrollador es la practica constante, escribir muchas líneas de código, cometer errores y aprender de ellos (echando a perder se aprende). Así que además de leer y tomar notas es necesario practicar constantemente, porque (ya lo dice el viejo y conocido refrán) “la practica hace al maestro”.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-7785998604658543034?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/7785998604658543034/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=7785998604658543034' title='6 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/7785998604658543034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/7785998604658543034'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/03/la-practica-hace-al-maestro.html' title='La practica hace al maestro'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-6303218550082095563</id><published>2011-03-12T12:50:00.001-08:00</published><updated>2011-03-12T16:25:24.467-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NuGet'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>NuGet Manejador de paquetes</title><content type='html'>&lt;p&gt;Al trabajar en proyectos en .Net es común hacer uso de librerías de terceros, ya sean de código abierto e incluso de algunas con código propietario. Para usar estas librerías necesitaba ir al sitio de cada una de ellas y descargar la última versión (o la que necesitara) y descargar los archivos, después agregar una carpeta al nivel de mi archivo de solución de VisualStudio que acostumbraba llamarla “Lib” y ahí agregar los DLLs de terceros que usaría en mi solución.&lt;/p&gt;  &lt;p&gt;Ahora con &lt;a href="http://nuget.org" target="_blank"&gt;NuGet&lt;/a&gt;, el manejo de dependencias se simplifica. Lo primero que necesito es instalarlo, lo cual lo puedo hacer desde VisualStudio, usando el &lt;a href="http://msdn.microsoft.com/en-us/library/dd293638.aspx" target="_blank"&gt;Extension Manager&lt;/a&gt; y buscando “NuGet”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_GuIIcTHVIyM/TXvclgWL4gI/AAAAAAAAAPQ/dLfVR-COPAc/s1600-h/extension_manager_nuget%5B13%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="extension_manager_nuget" border="0" alt="extension_manager_nuget" src="http://lh5.ggpht.com/_GuIIcTHVIyM/TXvcmd78QbI/AAAAAAAAAPU/gDVtO6Ax5-I/extension_manager_nuget_thumb%5B11%5D.png?imgmax=800" width="244" height="157" /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;En algunas maquinas con esto fue suficiente, sin embrago (desconozco la razón) en una de mis maquina no pude instalarlo a través del extension manager. Lo que hice fue instalarlo desde &lt;a href="http://nuget.org" target="_blank"&gt;nuget.org&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_GuIIcTHVIyM/TXvcnTqML5I/AAAAAAAAAPY/5YWvFVxvYnk/s1600-h/nuget.org%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="nuget.org" border="0" alt="nuget.org" src="http://lh3.ggpht.com/_GuIIcTHVIyM/TXvcn0y0MKI/AAAAAAAAAPc/t4oXyXOgYys/nuget.org_thumb.png?imgmax=800" width="244" height="155" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Una vez instalado se debe de reiniciar VisualStudio y aparece una nueva opción en el menú de Tools (Herramientas) y en el menú de View &amp;gt; Other Windows&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_GuIIcTHVIyM/TXvcoSv2UdI/AAAAAAAAAPg/lzZ2I10CDIY/s1600-h/tools%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="tools" border="0" alt="tools" src="http://lh6.ggpht.com/_GuIIcTHVIyM/TXvcowArl-I/AAAAAAAAAPk/8EZPBfVpDYM/tools_thumb.png?imgmax=800" width="244" height="114" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Con esto se puede abrir la consola de NuGet (se necesita tener instalado PowerShell 2.0) y descargar e instalar desde ahí los paquetes (librerías) que se necesiten para el proyecto actual. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_GuIIcTHVIyM/TXvcpT-rEnI/AAAAAAAAAPo/abvXSi3HdtU/s1600-h/nuget_console%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="nuget_console" border="0" alt="nuget_console" src="http://lh4.ggpht.com/_GuIIcTHVIyM/TXvcp7_dyuI/AAAAAAAAAPs/V_6NTGeVjK4/nuget_console_thumb.png?imgmax=800" width="244" height="64" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;En un proyecto en particular necesitaba instalar &lt;a href="https://github.com/machine/machine.specifications"&gt;MSpec&lt;/a&gt;, para eso solo ejecuté en la consola de NuGet:&lt;/p&gt;  &lt;pre&gt;PM&amp;gt; Install-Package Machine.Specifications&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;NuGet se encargó del resto: descargar dlls, agregar referencias, etc. El único ajuste que tuve que hacer en mi manera de trabajar es que nuget usa una carpeta llamada “packages” en lugar de “lib” como yo lo hacia. Pero es un pequeño cambio que bien vale la pena para aprovechar lo que hace NuGet por mi.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-6303218550082095563?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/6303218550082095563/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=6303218550082095563' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6303218550082095563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6303218550082095563'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/03/nuget-manejador-de-paquetes.html' title='NuGet Manejador de paquetes'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_GuIIcTHVIyM/TXvcmd78QbI/AAAAAAAAAPU/gDVtO6Ax5-I/s72-c/extension_manager_nuget_thumb%5B11%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-265770616354611847</id><published>2011-03-08T21:10:00.002-08:00</published><updated>2011-03-09T14:47:31.905-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trabajo'/><title type='text'>Al desarrollador le gusta desarrollar</title><content type='html'>&lt;p&gt;Seguido leo (y escribo) comentarios, tweets, posts, etc sobre lo mal que la pasamos en ciertos proyectos en los que trabajamos. Aun y cuando lo que nos gusta hacer, como desarrolladores que somos, es desarrollar. ¿Entonces por qué es que surgen estas situaciones de descontento entre los desarrolladores?&lt;/p&gt;  &lt;p&gt;Considero que parte del problema es la falta de decisión que se tiene sobre el curso de algún proyecto, la arquitectura, metodología, framework, (peor cuando nos toca usar &lt;a href="http://www.developeando.com/2011/02/la-idea-de-nuestro-propio-framework.html"&gt;el intento de framework que hizo alguien más&lt;/a&gt;), etc. Esto hace que el desarrollador se sienta como un &lt;a href="http://en.wikipedia.org/wiki/Code_monkey"&gt;code monkey&lt;/a&gt;, alguien que hace la &lt;a href="http://es.wiktionary.org/wiki/talacha"&gt;talacha&lt;/a&gt; y no como alguien que desarrolla soluciones para las necesidades del cliente. No hay motivación.&lt;/p&gt;  &lt;p&gt;Al participar en proyectos con diferentes empresas he notado que en los proyectos que he sufrido mas frustración, al trabajar en ellos, es cuando el cliente ya eligió que usar y peor cuando ya eligió el como hacerlo. Al iniciar o continuar el desarrollo del proyecto me encuentro con que la decisión del cliente no fue la mejor, muchas veces basada en las viejas formas de hacer las cosas o basado en la tecnología que un tercero le vendió. Esto hace que haya cierta frustración en el desarrollo del proyecto porque estoy en problemas por culpa de alguien más.&lt;/p&gt;  &lt;p&gt;Este descontento también aparece cuando no se entienden bien las necesidades del cliente. Ya sea porque se trata de un sistema ya establecido y solo se pide que se corrijan algunos errores. Y no se quiere perder tiempo en explicarle al equipo la importancia de lo que hace el sistema. Esto hace que el desarrollador no sienta el proyecto como suyo y por lo tanto no sienta motivación para mejorarlo.&lt;/p&gt;  &lt;p&gt;En cambio cuando se trabaja en proyectos donde el cliente explica, no solo las necesidades sino también las razones por las cuales es importante. Incluso que nos explique porque eligió la posible solución y el como. De una manera en la que el equipo pueda aportar y mejorar esa idea. Es cuando se siente una mayor motivación para trabajar en ese proyecto. &lt;/p&gt;  &lt;p&gt;Hace poco grabamos un &lt;a href="http://www.dev3cast.com/2011/02/17/scrum/"&gt;episodio&lt;/a&gt; de &lt;a href="http://www.dev3cast.com/"&gt;Dev3Cast&lt;/a&gt; y ahí nos comentaba &lt;a href="http://twitter.com/makalyka"&gt;Iván González&lt;/a&gt; sobre la importancia de la confianza en el equipo. Y la importancia de la opinión de todos los desarrolladores, incluso de aquellos que aun no tienen experiencia. &lt;/p&gt;  &lt;p&gt;Esto puede ayudar a que el desarrollador sienta el proyecto como suyo y este dispuesto a dar un poco más de esfuerzo con tal de que se logre un mejor resultado, mientras hace lo que le gusta. Los managers deben de tomar ventaja de que al desarrollador le gusta desarrollar.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-265770616354611847?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/265770616354611847/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=265770616354611847' title='6 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/265770616354611847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/265770616354611847'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/03/al-desarrollador-le-gusta-desarrollar.html' title='Al desarrollador le gusta desarrollar'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-6190814181981724558</id><published>2011-02-18T20:52:00.001-08:00</published><updated>2011-11-08T09:31:38.130-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trabajo'/><title type='text'>La idea de nuestro propio “Framework”</title><content type='html'>Creo que muchos de los desarrolladores hemos tenido la idea e incluso iniciado el desarrollo alguna vez de nuestro propio “Framework” para generar aplicaciones. No veo malo el escribir otro Framework. Pero muchas veces solo terminan limitándose, haciendo lo fácil mas fácil y lo difícil casi imposible, poco flexibles. Se vuelven una carga que mantener. Algo con lo que los desarrolladores no están muy entusiasmados en trabajar, porque prefieren usar algo nuevo.&lt;br /&gt;He notado que esos pequeños Frameworks tienen algunas características en común (esta no es una receta, solo son unos de los problemas comunes que he visto en esos pequeños frameworks privados):&lt;br /&gt;&lt;b&gt;No se conocen los frameworks existentes: &lt;/b&gt;Lo más seguro es que ya exista algo que hace lo que se quiere lograr. Puede que se trate de un problema resuelto. Quizás lo mejor sea contribuir a un proyecto open source existente, agregando las características que se necesitan. Si la idea es hacer lo mismo que ya hace otro Framework, debe haber una razón más fuerte que el solo no tomarse la molestia de aprender a trabajar con los existentes.&lt;br /&gt;&lt;b&gt;No tienen un proyecto real donde usarlo: &lt;/b&gt;Sin una aplicación real donde probar los conceptos es difícil que se le atine a lo que realmente se necesita en un proyecto real. Puede tomarse en cuenta la experiencia de proyectos anteriores. Aun así creo que uno de los riesgos que se corre al no tener un proyecto donde probarlo es agregar características que no se necesitan u omitir las necesarias.&lt;br /&gt;&lt;b&gt;No son de código abierto (Open Source):&lt;/b&gt; Varios de estos pequeños frameworks son para uso exclusivo de quien lo desarrollo y a veces no quieren mostrarle el código a nadie fuera de la empresa, como si alguien les fuera a robar la idea y teniendo el secreto ya nadie necesitaría (contrataría) del autor del framework. Cuando en realidad es todo lo contrario, Al liberar el código de la librería/framework ayuda a que el código tenga mas ojos; y mas ojos pueden ayudar a que el proyecto sea mejor. Además de que es una buena oportunidad de que el autor se de a conocer en la comunidad (publicidad) y que la comunidad se beneficie de esto, ambas partes ganan, pero sobre todo código.&lt;br /&gt;&lt;b&gt;No conocen la teoría:&lt;/b&gt; Conocer la teoría para que la practica tenga mas sentido. Cuando el proyecto tiene buenas bases teóricas logra ser mas consistente en la manera como esta desarrollado y tanto la &lt;a href="http://es.wikipedia.org/wiki/Mantenibilidad"&gt;mantenebilidad&lt;/a&gt;, como su extensibilidad generalmente logran ser mayor.&lt;br /&gt;&lt;b&gt;Quieren abarcar mucho&lt;/b&gt;:&lt;b&gt;&amp;nbsp;&lt;/b&gt;El no tener un objetivo claro o un problema concreto el cual se quiere resolver termina generando una gran cantidad de código que nadie quiere usar.&lt;br /&gt;El desarrollo de un framework es una buena actividad para ser un mejor desarrollador, es algo que se debe intentar (más si es en un proyecto open source). La innovación puede ocurrir. Si conociendo las soluciones existentes se cree necesitar una opción mas, pues adelante.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-6190814181981724558?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/6190814181981724558/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=6190814181981724558' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6190814181981724558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6190814181981724558'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/02/la-idea-de-nuestro-propio-framework.html' title='La idea de nuestro propio “Framework”'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2400307333335932669</id><published>2011-02-11T20:09:00.006-08:00</published><updated>2011-02-12T12:00:19.705-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trabajo'/><title type='text'>Comunicación con messenger en la oficina</title><content type='html'>Ahora que volví a trabajar desde la oficina, con compañeros de trabajo (antes trabajaba desde mi casa) he notado que mucha de la comunicación entre los desarrolladores, incluso con la administración, se da a través del messenger e incluso por redes sociales como twitter y facebook (aunque por estas la comunicación es mas informal). Es algo que ya venia haciendo, pero pensé que era porque no estaba físicamente ahí con ellos.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Al principio no me gustaba tanto y prefería levantarme e ir al lugar de los demás. Empece a notar que era de los pocos que hacia eso y sentía que estaba distrayendo a la persona que con la estaba hablando y a los de su alrededor.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ahora uso mas el messenger (mensajero en español) para hablar con mis compañeros (aunque estén a lado mio) y he notado que tiene algunos beneficios que explico a continuación.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Debido a que somos muchos personas trabajando en la oficina, es casi imposible que a todos nos guste la misma música; por eso el uso de audífonos es algo común. Esto hace que al escuchar música (con los audífonos) logres cierta concentración hacia la computadora. El problema con una interrupción en persona es que obliga a "desconectarse" para poder atenderla. En cambio si la interrupción es a través del mensajero; entonces se puede atrasar un poco, no "desconectarte" en ese momento y después atender el mensaje cuando se tenga oportunidad. Incluso aunque se atienda el mensaje de inmediato, el no tener que poner en pausa la música y quitarte los audífonos para responder, logra que se pierda menos la concentración de lo que se esta haciendo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Esto me hace pensar que si toda la comunicación se da a través de medios electrónicos, entonces ¿por que no trabajamos todos desde nuestras casas? Con las herramientas actuales de comunicación fácil podríamos todos trabajar desde casa; pero el problema es que no todos pueden. Hay para quienes trabajar desde casa implica muchas distracciones en persona, o simplemente se distraen por otras cosas, etc.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Extraño los días en que todo el equipo trabajaba escuchando la misma música (o sin música), cuando no había necesidad de audífonos. Y hablábamos sin necesidad del mensajero, pero ahora veo las ventajas y me parece una buena idea, porque hay quienes en la oficina no lo usan para hablar entre ellos y distraen a los demás con sus discusiones técnicas.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2400307333335932669?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2400307333335932669/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2400307333335932669' title='6 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2400307333335932669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2400307333335932669'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/02/comunicacion-con-messenger-en-la.html' title='Comunicación con messenger en la oficina'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-6594463537994707985</id><published>2011-02-03T20:32:00.006-08:00</published><updated>2011-02-03T21:14:03.089-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Desarrollo Web Arrastrando y Soltando</title><content type='html'>Hace unos días necesitaba realizar una aplicación web en muy poco tiempo. Debía mostrar un demo en un día; así que decidí olvidarme de las buenas practicas por un día y (usando ASP.NET WebForms) empezar a arrastrar y soltar componentes a mi página. Diseñando las paginas de captura y lectura (Grids) sin ver el markup que VisualStudio me iba generando.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tenia mucho tiempo sin trabajar en Design View, pero no tenia tiempo de ponerme a editar el markup a mano. Una vez creadas las páginas (a la drag and drop) usando el ratón empece a conectar mis GridViews y DropDownsLists usando LinqDataSources. Todo esto con la ayuda de wizards, en algunas consultas utilice views definidas en la base de datos (MS SQL Server) también con la ayuda de diseñadores, no use SQL para definir mis views. (Creo que tenia años sin usar Views y menos de usar el query designer).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No pudieron faltar los lugares donde necesite algo de código y para ello LinqToSql me ayudo a realizar las consultas y/o actualizaciones a la base de datos. Como no tenia mucho tiempo y el código era poco opté por escribirlo directamente en los event handlers (button_click, etc). Donde el código crecía un poco entonces sí agregaba una clase para no tener métodos muy largos.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Al final el demo se pudo terminar en un día y la aplicación estaba lista para usarse en un semana. El haber podido entregar una aplicación en una semana me ha hecho reconsiderar mi opinión sobre el desarrollo web hecho arrastrando y soltando. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Se que el problema vendrá con el mantenimiento. Precisamente esta es una de las razones por las que deje de hacer desarrollo arrastrando y soltando; Pero el poco código que escribí es facil de mantener (al menos así lo veo ahora) y si despues necesito algo mas complejo podria refactorizarlo y apoyarme en pruebas unitarias para eso.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No se...  me puso a pensar que tal vez si hubiera seguido las buenas practicas (TDD) quizas no hubiera terminado a tiempo y por lo tanto el proyecto se hubiera perdido.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Con esto no quiero decir que de ahora en adelante puro drag en drop (veremos como nos va con las nuevas features). Solo quise compartir mi experiencia en un proyecto pequeño y rápido del cual me sentí bien del código entregado y del poco tiempo que nos tomo hacerlo (Aunque fuera a la Drag and Drop) .&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-6594463537994707985?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/6594463537994707985/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=6594463537994707985' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6594463537994707985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6594463537994707985'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/02/desarrollo-web-arrastrando-y-soltando.html' title='Desarrollo Web Arrastrando y Soltando'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-4224690505586023749</id><published>2011-01-07T15:13:00.008-08:00</published><updated>2011-01-08T21:27:44.575-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='RubyOnRails'/><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans'/><title type='text'>Editores para RubyOnRails en Windows</title><content type='html'>Al trabajar con &lt;a href="http://rubyonrails.org/"&gt;RubyOnRails &lt;/a&gt;desde Windows he usado algunos editores y IDE's con sus ventajas y desventajas cada uno de ellos.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;El primero que utilicé fue &lt;a href="http://notepad-plus-plus.org/"&gt;Notepad++&lt;/a&gt;, porque ya lo tenia instalado en el sistema. Me gustó por lo ligero y rápido que responde el editor, pero lo que me hizo buscar opciones es que no coloreaba muy bien todos los archivos con los que trabajaba. Ademas de que no cuenta con un explorador del proyecto. Hay complementos para para tener una lista de carpetas, pero ninguna me gustó del todo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;La segunda herramienta que usé fue &lt;a href="http://www.blogger.com/www.netbeans.org"&gt;NetBeans&lt;/a&gt;. Ya había trabajado con NetBeans antes (desarrollando en java) así que no me fue difícil conocer el IDE. Me gustó trabajar con el IDE ya que estoy acostumbrado a usar uno en mi trabajo (trabajo con .Net en C# desde Visual Studio). Pero seguí buscando alternativas, ya que NetBeans es algo pesado y al buscar información, sobre como realizar ciertas tareas en rails, siempre encontraba ejemplos con la consola y simples editores. Al hacerlos en netbeans sentía como que hacia "trampa".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Intenté &lt;a href="http://aptana.com/products/studio2"&gt;aptana &lt;/a&gt;pero estaba lentísimo en mi maquina, así que lo des-instale luego luego.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Buscando algo parecido a &lt;a href="http://macromates.com/"&gt;TextMate &lt;/a&gt;encontré &lt;a href="http://www.e-texteditor.com/"&gt;E-Editor&lt;/a&gt; que según dicen es algo así como el textmate para windows; pero es de pago y actualmente no cobro por desarrollar en ruby. Por lo que seguí buscando una opción gratis.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Así fue como encontré &lt;a href="http://intype.info/home/index.php"&gt;intype&lt;/a&gt; un editor muy sencillo y bonito que cuenta con un &lt;i&gt;project view&lt;/i&gt; (que es simplemente una carpeta raíz en una vista de árbol, no tiene un archivo con la definición del proyecto). Lo estuve usando por algún tiempo junto con la consola de comandos; pero a ratos sentía que tenia que escribir mucho, no te auto-completa nada...entonces seguí buscando.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Encontré &lt;a href="http://www.activestate.com/komodo-edit"&gt;Komodo&lt;/a&gt;, un editor sencillo que si te auto-completa algunas cosas y ademas puedes definir tus propias plantillas, funciona bien. Sin embargo nunca me terminó de gustar. Tiene algunos detalles como no poder abrir un archivo rápidamente con solo teclear parte del nombre y otras cosillas que hacían que no me gustara del todo. Lo usaba junto con la consola de comandos.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Y así después de intentar con algunos editor regresé a NetBeans, donde todo esta integrado, No necesito la consola para usar los generadores básicos, ni para la mayoría de los comandos de &lt;i&gt;rake&lt;/i&gt;, ni para iniciar el servidor Web. Es por eso que por ahora mi editor (IDE) para trabajar en &lt;i&gt;ruby on rails&lt;/i&gt; en windows es netbeans.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Siento que me sirvió el estar usando editores sencillos y usar la consola. Para conocer (practicar) a bien los comandos. Pero una vez que los conozco me gusta lo rápido que los uso desde NetBeans...obviamente esta opinión puede cambiar de un momento a otro sin previo aviso.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Aun me falta por intentar Vim...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-4224690505586023749?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/4224690505586023749/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=4224690505586023749' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4224690505586023749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4224690505586023749'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2011/01/editores-para-rubyonrails-en-windows.html' title='Editores para RubyOnRails en Windows'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-5869603575498708414</id><published>2010-12-23T16:16:00.004-08:00</published><updated>2010-12-23T16:23:05.632-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TJNET'/><title type='text'>Hablando sobre Certificaciones</title><content type='html'>Hace tiempo participé en el podcast dev3cast donde hablamos sobre &lt;span style="font-size:100%;"&gt;&lt;a href="http://www.dev3cast.com/2010/05/18/certificaciones-%c2%bfpara-que/" rel="bookmark" title="Permanent link to Certificaciones ¿para qué?"&gt;Certificaciones ¿para qué?&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-5869603575498708414?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/5869603575498708414/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=5869603575498708414' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5869603575498708414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5869603575498708414'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/12/hablando-sobre-certificaciones.html' title='Hablando sobre Certificaciones'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-4413567889884904792</id><published>2010-12-10T11:57:00.007-08:00</published><updated>2010-12-10T15:50:31.752-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='RubyOnRails'/><title type='text'>Instalar Ruby on Rails 3 en Windows</title><content type='html'>He estado explicando en el trabajo los pasos para iniciar una aplicación con rails 3 en windows, así que pensé que seria buena idea escribir los pasos en un post:&lt;br /&gt;&lt;br /&gt;A continuación muestro los pasos que sigo para instalar &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; por primera vez en Windows.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Lo primero que necesitamos es instalar &lt;a href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt;, lo podemos descargar desde &lt;a href="http://rubyinstaller.org/"&gt;rubyinstaller.org&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Bajar el DLL de &lt;a href="http://www.sqlite.org/download.html"&gt;sqlite3&lt;/a&gt; y copiarlo a la carpeta bin de la carpeta donde se instaló ruby&lt;/li&gt;&lt;li&gt;Instalar rails, para eso desde la consola de comandos podemos ejecutar "gem install rails". Esto bajará e instalará la última versión estable de Rails.&lt;/li&gt;&lt;li&gt;Ahora si podemos crear una nueva aplicación ejecutando en la consola: "rails new app_name" (donde app_name es el nombre de tu aplicación). Después nos cambiamos al directorio de la aplicación (cd app_name).&lt;/li&gt;&lt;li&gt;Para que la aplicación corra necesitamos instalar las gemas necesarias por nuestro proyecto, si vemos el archivo gemfile que esta en la raíz del proyecto nos damos cuenta de las gemas necesarias (sqlite3-ruby por ejemplo). Para eso podemos correr desde la consola "bundle install"; Lo que pasará es que se instalarán todas las gemas que necesita nuestra aplicación (según el gemfile).&lt;/li&gt;&lt;li&gt;Ahora podemos arrancar nuestro servidor web usando "rails server" (o simplemente "rails s")&lt;/li&gt;&lt;li&gt;Una vez que esta corriendo el servidor web podemos abrir una ventana de nuestro navegador e ir a la dirección "http://localhost:3000" y podremos ver nuestra aplicación corriendo.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Antes estaba usando NetBeans para realizar la mayoría de estas tareas, ahora prefiero hacerlo en la consola, de hecho como editor estoy usando &lt;a href="http://intype.info/"&gt;intype &lt;/a&gt;(aun sigo pensando que netbeans es una buena opcion, sobre todo si vas empezando).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-4413567889884904792?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/4413567889884904792/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=4413567889884904792' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4413567889884904792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4413567889884904792'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/12/instalar-ruby-on-rails-3-en-windows.html' title='Instalar Ruby on Rails 3 en Windows'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-4260416132632129601</id><published>2010-10-07T21:15:00.003-07:00</published><updated>2010-10-22T12:30:28.520-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>Permiso para hacer TDD</title><content type='html'>&lt;p&gt;Al estar en platicas/presentaciones sobre &lt;a href="http://www.developeando.com/2009/07/tdd-desarrollo-guiado-por-pruebas.html" target="_blank"&gt;TDD&lt;/a&gt; (Test Driven Development) donde los participantes son gente que ya esta trabajando. La mayoría de los participantes coincide en que es una buena practica realizar el desarrollo guiado por pruebas. Sin embargo una pregunta que surge frecuentemente es ¿Como convenzo a mi jefe de hacer TDD? &lt;/p&gt;  &lt;p&gt;Bueno para empezar no creo que un equipo de desarrollo deba pedir permiso para escribir mejor código, debería ser su obligación. Todos deberíamos de tratar de realizar cada vez un mejor trabajo. Mientras se entreguen resultados con calidad no debería de haber problema con los jefes.&lt;/p&gt;  &lt;p&gt;Es claro que el realizar pruebas unitarias aumenta la cantidad de código escrito. Pero solo es eso, mas código y de mejor calidad. Si bien es cierto que eso implica mas tiempo (al principio), también es cierto que el tiempo invertido en el código de una prueba es menor al tiempo que se invierte en mantener el código después o en encontrar un bug que una prueba (y un mejor diseño) nos hubiera evitado. Al final estamos escribiendo mejor código que prácticamente ya esta probado. Y al realizar TDD frecuentemente el tiempo para realizar prueba e implementación mejora.&lt;/p&gt;  &lt;p&gt;Entonces al realizar TDD pasa lo siguiente: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Mejora el diseño &lt;/li&gt;    &lt;li&gt;Mejora el código, es mas fácil modificarlo después &lt;/li&gt;    &lt;li&gt;Aumenta el numero de clases (código)&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Ahora yo te pregunto ¿Necesitas convencer a tu jefe de que te deje escribir una clase? &lt;/p&gt;  &lt;p&gt;Creo que la respuesta es no; así que solo hazlo. Escribe tus pruebas unitarias sin hacer una junta con tu jefe. Hazlo como parte del desarrollo normal del proyecto. Pero, si la respuesta es sí, es decir que necesitas convencer a tu jefe que te deje escribir una clase o un archivo con código entonces quizás tengas un problema mas grande.&lt;/p&gt;  &lt;p&gt;Si tu estas convencido que es lo mejor, no esperes a convencer a otros para sentir que tienes la razón. Solo haz lo mejor.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-4260416132632129601?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/4260416132632129601/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=4260416132632129601' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4260416132632129601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4260416132632129601'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/10/permiso-para-hacer-tdd.html' title='Permiso para hacer TDD'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-1190775299956334268</id><published>2010-09-30T15:40:00.001-07:00</published><updated>2010-09-30T15:45:03.609-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TJNET'/><category scheme='http://www.blogger.com/atom/ns#' term='MVP'/><category scheme='http://www.blogger.com/atom/ns#' term='IoC'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Model View Presenter en ASP.NET WebForms</title><content type='html'>&lt;p&gt;En la &lt;a href="http://www.tjnet.org/Eventos/1976.aspx" target="_blank"&gt;reunión 37&lt;/a&gt; de la &lt;a href="http://www.tjnet.org" target="_blank"&gt;comunidad Tijuana Net&lt;/a&gt;, realizada el pasado 29 de Septiembre en la &lt;a href="http://uabc.mx" target="_blank"&gt;Universidad Autónoma de Baja California&lt;/a&gt;. Hablé sobre el patrón MVP (&lt;a href="http://en.wikipedia.org/wiki/Model-view-presenter" target="_blank"&gt;Model View Presenter&lt;/a&gt;) en aplicaciones escritas usando &lt;a href="http://www.asp.net/web-forms" target="_blank"&gt;ASP.NET WebForms&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Actualmente considero una mejor alternativa utilizar el framework &lt;a href="http://www.asp.net/mvc" target="_blank"&gt;ASP.NET MVC&lt;/a&gt; sobre WebForms sin embargo, por diversos motivos, muchos de nosotros aun tenemos que trabajar en aplicaciones escritas con WebForms. Es por ello que me pareció buena idea presentar como aplicar este patrón y así quienes aun trabajamos en WebForms podamos obtener algunas de las ventajas de &lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns" target="_blank"&gt;separación de intereses&lt;/a&gt; y capacidad de &lt;a href="http://www.developeando.com/2009/07/tdd-desarrollo-guiado-por-pruebas.html" target="_blank"&gt;pruebas&lt;/a&gt; que brinda MVC.&lt;/p&gt;  &lt;p&gt;En la presentación inicie una aplicación WebForms de manera “tradicional” después la modifiqué para poder aplicar el patrón MVP y así tener la posibilidad de realizar &lt;a href="http://www.developeando.com/2009/07/tdd-desarrollo-guiado-por-pruebas.html" target="_blank"&gt;pruebas unitarias&lt;/a&gt; al código que antes estaba en el &lt;em&gt;code behind&lt;/em&gt;. En la segunda parte de la presentación modifiqué una vez mas el código de la aplicación para poder tener una estructura de clases reutilizable, además de utilizar un &lt;a href="http://www.developeando.com/2010/03/inversion-de-control-ioc.html" target="_blank"&gt;contenedor de dependencias&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Abajo pueden ver la presentación y el material que se utilizó. Agradezco sus comentarios que puedan ayudar a mejorar siguientes presentaciones. De igual forma si tienen alguna duda sobre la presentación no duden en hacérmela llegar a través de los comentarios del blog.&lt;/p&gt;  &lt;p&gt;Agradezco también a todos los asistentes su presencia y participación durante la reunión. Y claro a la &lt;a href="http://www.tjnet.org" target="_blank"&gt;comunidad Tijuana Net&lt;/a&gt; y a su líder &lt;a href="http://msmvps.com/blogs/gflores/" target="_blank"&gt;Gabriel Flores&lt;/a&gt; por hacer posible estas reuniones.&lt;/p&gt;  &lt;h2&gt;&lt;font size="2" face="Verdana"&gt;Screencast&lt;/font&gt;&lt;/h2&gt; &lt;object id="scPlayer" class="embeddedObject" type="application/x-shockwave-flash" data="http://content.screencast.com/users/gfloresr/folders/Default/media/48d3c5fd-60b1-48f0-9056-ece7acab516c/mp4h264player.swf" height="400" width="600"&gt; &lt;param name="movie" value="http://content.screencast.com/users/gfloresr/folders/Default/media/48d3c5fd-60b1-48f0-9056-ece7acab516c/mp4h264player.swf"&gt; &lt;param name="quality" value="high"&gt; &lt;param name="bgcolor" value="#FFFFFF"&gt; &lt;param name="flashVars" value="thumb=http://content.screencast.com/users/gfloresr/folders/Default/media/48d3c5fd-60b1-48f0-9056-ece7acab516c/FirstFrame.jpg&amp;amp;containerwidth=600&amp;amp;containerheight=400&amp;amp;content=http://content.screencast.com/users/gfloresr/folders/Default/media/48d3c5fd-60b1-48f0-9056-ece7acab516c/R37-ASPNETMVP.mp4&amp;amp;blurover=false"&gt; &lt;param name="allowFullScreen" value="true"&gt; &lt;param name="scale" value="showall"&gt; &lt;param name="allowScriptAccess" value="always"&gt; &lt;param name="base" value="http://content.screencast.com/users/gfloresr/folders/Default/media/48d3c5fd-60b1-48f0-9056-ece7acab516c/"&gt; &lt;video controls="controls" height="400" width="600"&gt;&lt;br&gt;  &lt;source src="http://content.screencast.com/users/gfloresr/folders/Default/media/48d3c5fd-60b1-48f0-9056-ece7acab516c/R37-ASPNETMVP.mp4" type="video/mp4;"&gt;&lt;br&gt;  &lt;b&gt;Your browser cannot play this video. &lt;a target="_blank" href="http://www.screencast.com/handlers/redirect.ashx?target=viewingembededhelp"&gt;Learn how to fix this&lt;/a&gt;.&lt;/b&gt; &lt;/video&gt; &lt;/object&gt;  &lt;h2&gt;&lt;font size="2" face="Verdana"&gt;Fotos&lt;/font&gt;&lt;/h2&gt; &lt;iframe style="padding-bottom: 0pt; background-color: rgb(252,252,252); padding-left: 0pt; width: 320px; padding-right: 0pt; height: 240px; padding-top: 0pt" title="Preview" marginheight="0" src="http://cid-b4329e20a9381067.office.live.com/embedphoto.aspx/Pictures/Fotos%20de%20Eventos%20TJNET/Fotos%20R37/100%5E_3553.JPG" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;iframe style="padding-bottom: 0pt; background-color: rgb(252,252,252); padding-left: 0pt; width: 98px; padding-right: 0pt; height: 115px; padding-top: 0pt" title="Preview" marginheight="0" src="http://cid-b4329e20a9381067.office.live.com/embedicon.aspx/Pictures/Fotos%20de%20Eventos%20TJNET/Fotos%20R37" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;  &lt;h2&gt;&lt;font size="2" face="Verdana"&gt;Proyecto de ejemplo&lt;/font&gt;&lt;/h2&gt; &lt;iframe style="padding-bottom: 0pt; background-color: rgb(252,252,252); padding-left: 0pt; width: 98px; padding-right: 0pt; height: 115px; padding-top: 0pt" title="Preview" marginheight="0" src="http://cid-b4329e20a9381067.office.live.com/embedicon.aspx/Eventos%20TJNET/R37/Pizzeria.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;  &lt;br /&gt;  &lt;br /&gt;&lt;font size="2" face="Verdana"&gt;Reuniones previas mencionadas (para ver los screencasts):    &lt;br /&gt;&lt;a href="/Eventos/1860.aspx" target="_blank"&gt;Test Driven Development &lt;/a&gt;    &lt;br /&gt;&lt;a href="/Eventos/1920.aspx" target="_blank"&gt;IoC containers&lt;/a&gt; &lt;/font&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-1190775299956334268?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/1190775299956334268/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=1190775299956334268' title='4 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1190775299956334268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1190775299956334268'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/09/model-view-presenter-en-aspnet-webforms.html' title='Model View Presenter en ASP.NET WebForms'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-771906539795581109</id><published>2010-07-26T11:31:00.001-07:00</published><updated>2010-07-26T11:31:14.549-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Eduardo Ramón Cornejo Portillo</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_GuIIcTHVIyM/TE3Ubzpq18I/AAAAAAAAANs/cx7dHXD9wt4/s1600-h/moto_0620%5B3%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="moto_0620" border="0" alt="moto_0620" align="right" src="http://lh3.ggpht.com/_GuIIcTHVIyM/TE3Uce_YkuI/AAAAAAAAANw/AoANfgQKDVo/moto_0620_thumb%5B1%5D.jpg?imgmax=800" width="184" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Mi hijo Eduardo Ramón nació el 24 de Julio del 2010 a las 5:41 am. Le gusta dormir de día y estar despierto en la noche.    &lt;br /&gt;Peso 3.3 Kg y midió 0.52 m al nacer.&lt;/p&gt;  &lt;p&gt;Su &lt;a href="http://www.developeando.com/2006/08/sara-mercedes-cornejo-portillo.html" target="_blank"&gt;hermana&lt;/a&gt;, mamá y papá estamos muy contentos.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-771906539795581109?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/771906539795581109/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=771906539795581109' title='10 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/771906539795581109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/771906539795581109'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/07/eduardo-ramon-cornejo-portillo.html' title='Eduardo Ramón Cornejo Portillo'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_GuIIcTHVIyM/TE3Uce_YkuI/AAAAAAAAANw/AoANfgQKDVo/s72-c/moto_0620_thumb%5B1%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-5958715962298898815</id><published>2010-07-19T16:27:00.001-07:00</published><updated>2010-07-19T16:44:18.472-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cucumber'/><category scheme='http://www.blogger.com/atom/ns#' term='BDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='RubyOnRails'/><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans'/><title type='text'>Iniciando con RubyOnRails Parte 5 – Instalando Cucumber</title><content type='html'>&lt;p&gt;En este &lt;a href="http://www.viddler.com/explore/mhcornejo/videos/1/" target="_blank"&gt;screencast&lt;/a&gt; muestro como instalé &lt;a href="http://cukes.info/" target="_blank"&gt;cucumber&lt;/a&gt; usando &lt;a href="http://netbeans.org/" target="_blank"&gt;NetBeans&lt;/a&gt;. Además instalé un plugin para NetBeans y así ejecutar las features desde el IDE&lt;/p&gt; &lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="437" height="336" id="viddler_d8f113f8"&gt;&lt;param name="movie" value="http://www.viddler.com/simple/d8f113f8/" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;embed src="http://www.viddler.com/simple/d8f113f8/" width="437" height="336" type="application/x-shockwave-flash" allowScriptAccess="always" allowFullScreen="true" name="viddler_d8f113f8"&gt;&lt;/embed&gt;&lt;/object&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-5958715962298898815?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/5958715962298898815/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=5958715962298898815' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5958715962298898815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5958715962298898815'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/07/iniciando-con-rubyonrails-parte-5.html' title='Iniciando con RubyOnRails Parte 5 – Instalando Cucumber'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2220684234835789922</id><published>2010-07-06T17:12:00.001-07:00</published><updated>2010-07-06T17:12:19.806-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='RubyOnRails'/><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans'/><title type='text'>Iniciando con RubyOnRails Parte 4</title><content type='html'>&lt;p&gt;Sigo con la aplicación en &lt;a href="http://rubyonrails.org/" target="_blank"&gt;RubyOnRails&lt;/a&gt; sobre &lt;a href="http://netbeans.org/" target="_blank"&gt;NetBeans&lt;/a&gt;, en esta ocasión en el &lt;a href="http://www.youtube.com/watch?v=a44Y20Zw6V4" target="_blank"&gt;screencast&lt;/a&gt; escribí la implementación de algunos de los métodos del guestscontroller&lt;/p&gt; &lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/a44Y20Zw6V4&amp;amp;hl=en_US&amp;amp;fs=1?rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/a44Y20Zw6V4&amp;amp;hl=en_US&amp;amp;fs=1?rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2220684234835789922?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2220684234835789922/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2220684234835789922' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2220684234835789922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2220684234835789922'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/07/iniciando-con-rubyonrails-parte-4.html' title='Iniciando con RubyOnRails Parte 4'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-3271541135456790158</id><published>2010-06-29T10:57:00.002-07:00</published><updated>2010-10-16T15:34:53.367-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='RubyOnRails'/><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans'/><title type='text'>Iniciando con RubyOnRails Parte 3</title><content type='html'>&lt;p&gt;Aprovechando un poco de tiempo libre que tenia agregué algo de validación a la aplicación “Traje”, agregue el modelo y empecé el controlador para registrar invitados a las reuniones. El &lt;a href="http://www.youtube.com/watch?v=e39-6LziAR8" target="_blank"&gt;screencast&lt;/a&gt; dura 7 minutos aproximadamente&lt;/p&gt; &lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/e39-6LziAR8&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;rel=0"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/e39-6LziAR8&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-3271541135456790158?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/3271541135456790158/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=3271541135456790158' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3271541135456790158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3271541135456790158'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/06/iniciando-con-rubyonrails-parte-3.html' title='Iniciando con RubyOnRails Parte 3'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-3440113987507578110</id><published>2010-06-28T14:12:00.001-07:00</published><updated>2010-06-28T14:12:14.252-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='RubyOnRails'/><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans'/><title type='text'>Iniciando con RubyOnRails Parte 2</title><content type='html'>&lt;p&gt;Sigo aprendiendo RubyOnRails, en este &lt;a href="http://www.youtube.com/watch?v=WS7bo0CNmsQ" target="_blank"&gt;screencast&lt;/a&gt; veo como agregar un campo a mi modelo, generando una migración. También veo como usar vistas parciales para reutilizar partes en las vistas.&lt;/p&gt; &lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/WS7bo0CNmsQ&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/WS7bo0CNmsQ&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-3440113987507578110?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/3440113987507578110/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=3440113987507578110' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3440113987507578110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3440113987507578110'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/06/iniciando-con-rubyonrails-parte-2.html' title='Iniciando con RubyOnRails Parte 2'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-7845836164675255095</id><published>2010-06-24T23:02:00.001-07:00</published><updated>2010-06-25T00:01:24.872-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='RubyOnRails'/><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans'/><title type='text'>Iniciando Con RubyOnRails</title><content type='html'>&lt;p&gt;Hace tiempo que querido aprender RubyOnRails y por una cosa o la otra siempre lo posponía. Hace poco inicio la &lt;a href="http://twitter.com/tijuanarb" target="_blank"&gt;comunidad de Ruby en Tijuana&lt;/a&gt; lo cual me ha inspirado a aprender RubyOnRails aprovechando que puedo tener el apoyo y ayuda de la comunidad mientras aprendo. &lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;font color="#808080"&gt;Acá entre nos, una de las razones por las que no iniciaba con ruby era que pensaba comprarme una Mac. He visto que la mayoría de los desarrolladores de ruby es lo que usan. Pero realmente no la necesito y además tomando en cuenta que próximamente seré papá nuevamente :-), ese es un gasto que tendrá que esperar. Sin embargo puedo aprender sobre RubyOnRails desde Windows.&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;He decidido grabar lo que voy aprendiendo, en videos cortos de no mas de 10 minutos, para que así alguien que también se quiera animar quizás pueda ayudarse de mi experiencia. De igual forma alguien que tenga experiencia y vea lo que estoy haciendo pueda orientarme a través de los comentarios del blog, lo cual agradeceré. &lt;/p&gt;  &lt;p&gt;Para iniciar instalé ruby, rails y sqlite3 sobre Windows usando la información de esta &lt;a href="http://wiki.rubyonrails.org/getting-started/installation/windows" target="_blank"&gt;página&lt;/a&gt;. Intente con varios editores pero al final no encontré ninguno que me convenciera, además estoy muy acostumbrado a usar un IDE; así que por lo pronto iniciaré la aplicación usando &lt;a href="http://netbeans.org/" target="_blank"&gt;NetBeans&lt;/a&gt; (Ruby Bundle).&lt;/p&gt;  &lt;p&gt;La aplicación que intentaré realizar es un sitio donde pueda organizar “Reuniones de Traje”. Son reuniones donde cada uno de los asistentes trae algo para la reunión, el traje se refiere al verbo traer y no a la vestimenta (ej. “yo traje botana”) .&lt;/p&gt;  &lt;p&gt;Iniciando con la aplicación (&lt;a href="http://www.youtube.com/watch?v=YjyR2XT5xxs" target="_blank"&gt;screencast&lt;/a&gt; de 7 minutos y fracción)&lt;/p&gt; &lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/YjyR2XT5xxs&amp;amp;hl=es_MX&amp;amp;fs=1&amp;amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/YjyR2XT5xxs&amp;amp;hl=es_MX&amp;amp;fs=1&amp;amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-7845836164675255095?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/7845836164675255095/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=7845836164675255095' title='4 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/7845836164675255095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/7845836164675255095'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/06/iniciando-con-rubyonrails.html' title='Iniciando Con RubyOnRails'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-9219886152133288505</id><published>2010-05-24T20:43:00.001-07:00</published><updated>2010-05-24T20:43:50.545-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='IoC'/><category scheme='http://www.blogger.com/atom/ns#' term='AltNet5'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>MEF Parte 4 - Imports</title><content type='html'>&lt;p&gt;Usando el mismo ejemplo de la aplicación “Saludador” (Iniciada en el Lanzamiento de VisualStudio 2010 en Tijuana) en el siguiente &lt;a href="http://screencast.com/t/MWRjZjhmYzQ" target="_blank"&gt;video&lt;/a&gt; muestro otras opciones al momento de importar partes de nuestro objeto usando &lt;a href="http://mef.codeplex.com/" target="_blank"&gt;MEF&lt;/a&gt;. En concreto ImportingConstructor y AllowDefault.&lt;/p&gt; &lt;object id="scPlayer" class="embeddedObject" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="600" height="400"&gt;&lt;param name="movie" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/583c0448-78b9-40da-90cf-8defd233a25b/jingswfplayer.swf"&gt;&lt;/param&gt;&lt;param name="quality" value="high"&gt;&lt;/param&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;/param&gt;&lt;param name="flashVars" value="containerwidth=600&amp;amp;containerheight=400&amp;amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/583c0448-78b9-40da-90cf-8defd233a25b/FirstFrame.jpg&amp;amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/583c0448-78b9-40da-90cf-8defd233a25b/MEF%20Parte%204%20-%20Imports.swf&amp;amp;blurover=false"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="scale" value="showall"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;param name="base" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/583c0448-78b9-40da-90cf-8defd233a25b/"&gt;&lt;/param&gt;&lt;embed id="scPlayerFF" class="embeddedObject" src="http://content.screencast.com/users/mhcornejo/folders/Jing/media/583c0448-78b9-40da-90cf-8defd233a25b/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="600" height="400" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=600&amp;containerheight=400&amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/583c0448-78b9-40da-90cf-8defd233a25b/FirstFrame.jpg&amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/583c0448-78b9-40da-90cf-8defd233a25b/MEF%20Parte%204%20-%20Imports.swf&amp;blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/mhcornejo/folders/Jing/media/583c0448-78b9-40da-90cf-8defd233a25b/" scale="showall"&gt;&lt;/embed&gt; &lt;/object&gt;  &lt;p&gt;Entradas Relacionadas:    &lt;br /&gt;&lt;a href="http://www.developeando.com/2010/04/introduccion-mef-parte-1.html" target="_blank"&gt;Introducción a MEF Parte 1&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://www.developeando.com/2010/04/introduccion-mef-parte-2.html" target="_blank"&gt;Introducción a MEF Parte 2&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://www.developeando.com/2010/05/introduccion-mef-parte-3-recomposicion.html" target="_blank"&gt;Introducción a MEF Parte 3 - Recomposición&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-9219886152133288505?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/9219886152133288505/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=9219886152133288505' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/9219886152133288505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/9219886152133288505'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/05/mef-parte-4-imports.html' title='MEF Parte 4 - Imports'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-6311110303267818333</id><published>2010-05-22T16:50:00.001-07:00</published><updated>2010-05-22T23:00:48.522-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='IoC'/><category scheme='http://www.blogger.com/atom/ns#' term='AltNet5'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Introducción a MEF Parte 3 - Recomposición</title><content type='html'>&lt;p&gt;Continuando con la aplicación de ejemplo sobre MEF, en esta ocasión muestro el concepto de recomposición de &lt;a href="http://mef.codeplex.com/" target="_blank"&gt;MEF&lt;/a&gt;. El cual permite cargar componentes de forma dinámica mientras nuestra aplicación corre.&lt;/p&gt;  &lt;p&gt;Algo a notar con este ejemplo fue que lo realice utilizando la librería de MEF que se encuentra en &lt;a href="http://mef.codeplex.com/" target="_blank"&gt;codeplex&lt;/a&gt;, usando VisualStudio 2008 con el .Net Framework 3.5. En lugar de utilizar VS2010 con el .Net 4.0 como lo había venido haciendo. Por ahora el código es el mismo para ambas versiones del framework.&lt;/p&gt; &lt;object id="scPlayer" class="embeddedObject" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="600" height="400"&gt;&lt;param name="movie" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/9cd0f4d3-e2f8-4b94-a1e9-52d8fca7931b/jingswfplayer.swf"&gt;&lt;/param&gt;&lt;param name="quality" value="high"&gt;&lt;/param&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;/param&gt;&lt;param name="flashVars" value="containerwidth=600&amp;amp;containerheight=400&amp;amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/9cd0f4d3-e2f8-4b94-a1e9-52d8fca7931b/FirstFrame.jpg&amp;amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/9cd0f4d3-e2f8-4b94-a1e9-52d8fca7931b/MEF%203ra%20Parte.swf&amp;amp;blurover=false"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="scale" value="showall"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;param name="base" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/9cd0f4d3-e2f8-4b94-a1e9-52d8fca7931b/"&gt;&lt;/param&gt;&lt;embed id="scPlayerFF" class="embeddedObject" src="http://content.screencast.com/users/mhcornejo/folders/Jing/media/9cd0f4d3-e2f8-4b94-a1e9-52d8fca7931b/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="600" height="400" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=600&amp;containerheight=400&amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/9cd0f4d3-e2f8-4b94-a1e9-52d8fca7931b/FirstFrame.jpg&amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/9cd0f4d3-e2f8-4b94-a1e9-52d8fca7931b/MEF%203ra%20Parte.swf&amp;blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/mhcornejo/folders/Jing/media/9cd0f4d3-e2f8-4b94-a1e9-52d8fca7931b/" scale="showall"&gt;&lt;/embed&gt; &lt;/object&gt;  &lt;p&gt;Como siempre mi meta es que estos videos (screencasts) no pasen de 5 min, por lo tanto si fui muy rápido, me falto algo o me equivoque, les agradeceré sus comentarios.&lt;/p&gt;  &lt;p&gt;También se puede ver el &lt;a href="http://screencast.com/t/ZGM5N2QzZD" target="_blank"&gt;video&lt;/a&gt; desde &lt;a href="http://screencast.com/t/ZGM5N2QzZD" target="_blank"&gt;screencast.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Post Relacionados:   &lt;br /&gt;&lt;a href="http://www.developeando.com/2010/04/introduccion-mef-parte-1.html" target="_blank"&gt;Introducción a MEF Parte 1&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://www.developeando.com/2010/04/introduccion-mef-parte-2.html" target="_blank"&gt;Introducción a MEF Parte 2&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-6311110303267818333?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/6311110303267818333/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=6311110303267818333' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6311110303267818333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6311110303267818333'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/05/introduccion-mef-parte-3-recomposicion.html' title='Introducción a MEF Parte 3 - Recomposición'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2682827359632820579</id><published>2010-05-21T21:54:00.002-07:00</published><updated>2010-05-21T22:18:05.247-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unity'/><category scheme='http://www.blogger.com/atom/ns#' term='IoC'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Como usar Unity IoC Container en ASP.NET MVC</title><content type='html'>&lt;p&gt;Una de las ventajas sobre la plataforma ASP.NET MVC sobre WebForms es que podemos utilizar el principio de inversión de control usando la inyección de dependencias (generalmente a través de los constructores). De tal forma que nuestros controladores reciben parámetros en los constructores. Esto hace que la plataforma MVC no pueda, por si sola (usando el DefaultControllerFactory), construir nuestros controladores usando el constructor que recibe parámetros. Es por ello que vemos ejemplos (como el proyecto plantilla de VisualStudio) donde se sobre carga el constructor con uno que no recibe parámetros y es el propio controlador el encargado de crear sus dependencias. Lo cual va en contra del principio de inversión de control. &lt;/p&gt;  &lt;p&gt;Resolver este problema es muy sencillo, basta con crear nuestro propio IControllerFactory que es el contrato que utiliza la plataforma MVC para construir los controladores. En este ejemplo nuestro controller factory hará uso de &lt;a href="http://unity.codeplex.com" target="_blank"&gt;Unity&lt;/a&gt; un Contenedor de dependencias (IoC container) para administrar las dependencias.&lt;/p&gt;  &lt;p&gt;La forma mas sencilla de crear un IControllerFactory es heredar del DefaultControllerFactory y redefinir el método GetControllerInstance. Aquí muestro el código:&lt;/p&gt;  &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; UnityControllerFactory: DefaultControllerFactory&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; IUnityContainer container;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; UnityControllerFactory(IUnityContainer container)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.container = container;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; IController GetControllerInstance(&lt;br /&gt;        RequestContext requestContext, Type controllerType)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (controllerType == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; )&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (IController)container.Resolve(controllerType);            &lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Como puede verse el UnityControllerFactory recibe un contenedor con las dependencias registradas, el cual utiliza para crear los controladores en el método GetControllerInstance. No hace falta registrar los controladores en el contenedor ya que Unity puede construir instancias de tipos no registrados.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Una vez creado nuestro controller factory es necesario indicarle a MVC (en concreto al ControllerBuilder) que utilice nuestro UnityControllerFactory para crear los controladores; el código queda algo así:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;br /&gt;  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var container = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; UnityContainer();&lt;br /&gt;&lt;span style="color: #008000"&gt;//aqui se registran las dependencias&lt;/span&gt;&lt;br /&gt;ControllerBuilder.Current.SetControllerFactory(&lt;br /&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; UnityControllerFactory(container));&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Esto se debe ejecutar al iniciar la aplicación (el Application_Start() en el Global.asax.cs).&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Como puede verse con muy poco código podemos estar usando un IoC container en nuestra aplicación ASP.NET MVC, no es complicado y el UnityControllerFactory puede reutilizarse en otras aplicaciones MVC. Así que, ya lo saben, no hay pretexto para no utilizar un contenedor de dependencias.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2682827359632820579?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2682827359632820579/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2682827359632820579' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2682827359632820579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2682827359632820579'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/05/como-usar-unitity-ioc-container-en.html' title='Como usar Unity IoC Container en ASP.NET MVC'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-4974664001049610532</id><published>2010-05-20T16:07:00.002-07:00</published><updated>2010-05-20T16:22:40.635-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LinqToSql'/><category scheme='http://www.blogger.com/atom/ns#' term='Unity'/><category scheme='http://www.blogger.com/atom/ns#' term='IoC'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Singleton por cada HTTP Request usando Unity IoC</title><content type='html'>&lt;p&gt;Hay ocasiones en las que necesitamos tener un objeto compartido por varios objetos en nuestra aplicacion web, similar al patrón singleton, pero solo para esa petición HTTP. Es decir sin compartirlo en toda la aplicación. &lt;/p&gt;  &lt;p&gt;Hace tiempo escribí sobre como &lt;a href="http://www.developeando.com/2009/12/compartir-datacontext-por-cada-http.html" target="_blank"&gt;compartir un LinqToSql DataContext por cada request&lt;/a&gt; en una aplicación web. Ahora utilizando &lt;a href="http://unity.codeplex.com/" target="_blank"&gt;Unity&lt;/a&gt; podemos lograr ese comportamiento y dejar que el contenedor de dependencias se encargue de darnos la instancia adecuada.&lt;/p&gt;  &lt;p&gt;Para manejar el tiempo de vida de las instancias unity utiliza lo que llama LifetimeManager, entonces lo primero que debemos hacer es crear nuestro LifetimeManager, en este caso lo llamaré HttpRequestLifetimeManager y heredamos de la clase abstracta Microsoft.Practices.Unity.LifetimeManager y debemos de definir 3 metodos GetValue, RemoveValue y SetValue. &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;public class &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(255,198,109)"&gt;HttpRequestLifetimeManager&lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;: LifetimeManager&lt;br /&gt;{                                                       &lt;br /&gt;   &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;object &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;key;                                          &lt;br /&gt;                                                        &lt;br /&gt;   &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;public &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;HttpRequestLifetimeManager(): &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;this&lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;(&lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;null&lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;)      &lt;br /&gt;   {                                                    &lt;br /&gt;   }                                                    &lt;br /&gt;                                                        &lt;br /&gt;   &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;public &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;HttpRequestLifetimeManager(&lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;object &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;key)        &lt;br /&gt;   {                                                    &lt;br /&gt;       &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;this&lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;.key = key;                                  &lt;br /&gt;   }                                                    &lt;br /&gt;                                                        &lt;br /&gt;   &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;public override object &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;GetValue()                    &lt;br /&gt;   {                                                    &lt;br /&gt;       &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;if &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;(key == &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;null&lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;) &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;return null&lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;;                    &lt;br /&gt;       &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;return &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;HttpContext.Current.Items[key];           &lt;br /&gt;   }                                                    &lt;br /&gt;                                                        &lt;br /&gt;   &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;public override void &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;RemoveValue()                   &lt;br /&gt;   {                                                    &lt;br /&gt;                                                        &lt;br /&gt;   }                                                    &lt;br /&gt;                                                        &lt;br /&gt;   &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;public override void &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;SetValue(&lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;object &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;newValue)       &lt;br /&gt;   {                                                    &lt;br /&gt;       &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;if &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;(key == &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;null&lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;)                                 &lt;br /&gt;           key = newValue.GetType();                    &lt;br /&gt;                                                        &lt;br /&gt;       HttpContext.Current.Items[key] = newValue;       &lt;br /&gt;   }                                                    &lt;br /&gt;}                                                       &lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Lo que hace el HttpRequestLifetimeManager es guardar la instancia de la clase en el Items dictionary con el key que se le especifique en el constructor, si no se ha especificado un key, entonces utilizará el tipo del objeto para identificarlo en el diccionario.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Una vez teniendo nuestro LifetimeManager solo es cuestión de especificarle a unitity, al momento de registrar nuestro tipo, que utilice nuestro HttpRequestLifetimeManager para manejar el tiempo de vida de nuestra instancia. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Por ejemplo supongamos que tenemos declarados algunas clases (posiblemente repositorios) que recibe el constructor un DataContext algo como esto:&lt;/p&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;public class &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(255,198,109)"&gt;UserRepository &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;: IUserRepository       &lt;br /&gt;{                                                   &lt;br /&gt;   &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;readonly &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;MyDataContext db;                       &lt;br /&gt;                                                    &lt;br /&gt;   &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;public &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;UserRepository(MyDataContext db)          &lt;br /&gt;   {                                                &lt;br /&gt;       &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;this&lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;.db = db;                                &lt;br /&gt;   }                                                &lt;br /&gt;...                                                 &lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Si queremos que todos nuestros repositorios compartan el mismo MyDataContext por cada request, entonces configuramos nuestro contenedor (generalmente en el Global.asx.cs) de la siguiente manera:&lt;/p&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;var container = &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;new &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;UnityContainer();                             &lt;br /&gt;                                                                  &lt;br /&gt;container.RegisterType&amp;lt;IAccountRepository, AccountRepository&amp;gt;();  &lt;br /&gt;container.RegisterType&amp;lt;IUserRepository, UserRepository&amp;gt;();        &lt;br /&gt;                                                                  &lt;br /&gt;container.RegisterType&amp;lt;MyDataContext&amp;gt;(                            &lt;br /&gt;   &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;new &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;HttpRequestLifetimeManager(), &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: rgb(204,120,50)"&gt;new &lt;/span&gt;&lt;span style="background: rgb(30,30,30); color: white"&gt;InjectionConstructor()); &lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Ahí podemos ver como al registrar MyDataContext paso una instancia de la clase HttpRequestLifetimeManager para usar la misma instancia durante todo el request y además le paso un instancia de InjectionConstructor para indicarle que utilice el constructor sin argumentos de nuestra clase MyDataContext.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Una vez hecho esto nuestro contenedor se encargará de entregarnos repositorios que comparten el mismo datacontext por cada request.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-4974664001049610532?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/4974664001049610532/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=4974664001049610532' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4974664001049610532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4974664001049610532'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/05/singleton-por-cada-http-request-usando.html' title='Singleton por cada HTTP Request usando Unity IoC'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-1614357352586571601</id><published>2010-04-15T12:58:00.001-07:00</published><updated>2010-04-24T15:44:15.165-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='TJNET'/><category scheme='http://www.blogger.com/atom/ns#' term='IoC'/><category scheme='http://www.blogger.com/atom/ns#' term='AltNet5'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Introducción a MEF Parte 2</title><content type='html'>&lt;p&gt;Siguiendo con el ejemplo del &lt;a href="http://www.developeando.com/2010/04/introduccion-mef-parte-1.html" target="_blank"&gt;post anterior&lt;/a&gt; sobre &lt;a href="http://mef.codeplex.com/Wikipage" target="_blank"&gt;MEF&lt;/a&gt; (La aplicación para consola “Saludador” que presente en el Launch de Visual Studio 2010 en Tijuana). En este &lt;a href="http://screencast.com/t/ZTAwM2RlMzU" target="_blank"&gt;screencast&lt;/a&gt; muestro como usar MEF para que alguien que no tiene acceso al código fuente de la aplicación, pueda extenderla (plugins) y agregar sus propios saludos. &lt;/p&gt; &lt;object id="scPlayer" class="embeddedObject" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="600" height="400"&gt;&lt;param name="movie" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/40b1dda7-4ac3-400c-be35-4a3fa7053d9d/jingswfplayer.swf"&gt;&lt;/param&gt;&lt;param name="quality" value="high"&gt;&lt;/param&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;/param&gt;&lt;param name="flashVars" value="containerwidth=600&amp;amp;containerheight=400&amp;amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/40b1dda7-4ac3-400c-be35-4a3fa7053d9d/FirstFrame.jpg&amp;amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/40b1dda7-4ac3-400c-be35-4a3fa7053d9d/MEF%20Parte%202.swf&amp;amp;blurover=false"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="scale" value="showall"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;param name="base" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/40b1dda7-4ac3-400c-be35-4a3fa7053d9d/"&gt;&lt;/param&gt;&lt;embed id="scPlayerFF" class="embeddedObject" src="http://content.screencast.com/users/mhcornejo/folders/Jing/media/40b1dda7-4ac3-400c-be35-4a3fa7053d9d/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="600" height="400" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=600&amp;containerheight=400&amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/40b1dda7-4ac3-400c-be35-4a3fa7053d9d/FirstFrame.jpg&amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/40b1dda7-4ac3-400c-be35-4a3fa7053d9d/MEF%20Parte%202.swf&amp;blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/mhcornejo/folders/Jing/media/40b1dda7-4ac3-400c-be35-4a3fa7053d9d/" scale="showall"&gt;&lt;/embed&gt; &lt;/object&gt;  &lt;p&gt;Debido a que los videos solo los quiero realizar de 5 min, tuve que irme (quizás) un poco rápido. Como siempre cualquier comentario es bienvenido.&lt;/p&gt;  &lt;p&gt;Post relacionado: &lt;a href="http://www.developeando.com/2010/04/introduccion-mef-parte-1.html" target="_blank"&gt;Introducción a MEF Parte 1&lt;/a&gt;&lt;/p&gt; Código Fuente: &lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-b4329e20a9381067.skydrive.live.com/embedicon.aspx/Eventos%20TJNET/VS2010%20Launch/tjnet.Mef.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-1614357352586571601?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/1614357352586571601/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=1614357352586571601' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1614357352586571601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1614357352586571601'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/04/introduccion-mef-parte-2.html' title='Introducción a MEF Parte 2'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-5269411535127434435</id><published>2010-04-13T20:06:00.001-07:00</published><updated>2010-04-15T13:05:15.773-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='TJNET'/><category scheme='http://www.blogger.com/atom/ns#' term='IoC'/><category scheme='http://www.blogger.com/atom/ns#' term='AltNet5'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Introducción a MEF Parte 1</title><content type='html'>&lt;p&gt;En el pasado &lt;a href="http://tjnet.org/Eventos/1923.aspx" target="_blank"&gt;Launch de Visual Studio 2010 en Tijuana&lt;/a&gt; presenté el tema: Extendiendo Aplicaciones con &lt;a href="http://mef.codeplex.com/Wikipage" target="_blank"&gt;MEF&lt;/a&gt;. Debido a que olvide grabar la presentación, quise rehacer el ejemplo dividiéndolo en screencasts de no mas 5 min. Usando el mismo ejemplo que en la sesión. Espero sirva como introducción para quienes quieran conocer sobre &lt;a href="http://mef.codeplex.com/Wikipage" target="_blank"&gt;MEF&lt;/a&gt; (&lt;a href="http://mef.codeplex.com/Wikipage" target="_blank"&gt;Managed Extensibility Framework&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;El ejemplo trata de una aplicación para consola que tiene una lista de saludos, el usuario puede seleccionar el saludo que guste y ejecutarlo. La idea es que el saludador pueda ser extendido, de tal forma que yo (como desarrollador de la aplicación) o cualquier tercero pueda agregar saludos a la aplicación. &lt;/p&gt;  &lt;p&gt;En este primer &lt;a href="http://screencast.com/t/YjdiNjc3YjQt" target="_blank"&gt;video&lt;/a&gt;, muestro el funcionamiento básico de MEF (Importar, Exportar y Componer).&lt;/p&gt; &lt;object id="scPlayer" class="embeddedObject" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="600" height="400"&gt;&lt;param name="movie" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/2d91cbbf-6687-4027-903c-00c560395d36/jingswfplayer.swf"&gt;&lt;/param&gt;&lt;param name="quality" value="high"&gt;&lt;/param&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;/param&gt;&lt;param name="flashVars" value="containerwidth=600&amp;amp;containerheight=400&amp;amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/2d91cbbf-6687-4027-903c-00c560395d36/FirstFrame.jpg&amp;amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/2d91cbbf-6687-4027-903c-00c560395d36/MEF%20parte%201.swf&amp;amp;blurover=false"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="scale" value="showall"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;param name="base" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/2d91cbbf-6687-4027-903c-00c560395d36/"&gt;&lt;/param&gt;&lt;embed id="scPlayerFF" class="embeddedObject" src="http://content.screencast.com/users/mhcornejo/folders/Jing/media/2d91cbbf-6687-4027-903c-00c560395d36/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="600" height="400" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=600&amp;containerheight=400&amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/2d91cbbf-6687-4027-903c-00c560395d36/FirstFrame.jpg&amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/2d91cbbf-6687-4027-903c-00c560395d36/MEF%20parte%201.swf&amp;blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/mhcornejo/folders/Jing/media/2d91cbbf-6687-4027-903c-00c560395d36/" scale="showall"&gt;&lt;/embed&gt; &lt;/object&gt;  &lt;p&gt;Post Relacionado: &lt;a href="http://www.developeando.com/2010/04/introduccion-mef-parte-2.html" target="_blank"&gt;Introducción a MEF Parte 2&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-5269411535127434435?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/5269411535127434435/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=5269411535127434435' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5269411535127434435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5269411535127434435'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/04/introduccion-mef-parte-1.html' title='Introducción a MEF Parte 1'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-6939494833529527525</id><published>2010-03-30T18:42:00.004-07:00</published><updated>2010-03-30T18:51:28.152-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unity'/><category scheme='http://www.blogger.com/atom/ns#' term='TJNET'/><category scheme='http://www.blogger.com/atom/ns#' term='IoC'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Singleton con Unity</title><content type='html'>&lt;p&gt;En la pasada &lt;a href="http://tjnet.org/Eventos/1920.aspx" target="_blank"&gt;reunión&lt;/a&gt; de la &lt;a href="http://tjnet.org/" target="_blank"&gt;comunidad TJ.Net&lt;/a&gt; presenté el tema IoC, donde mostré un ejemplo usando el contenedor de dependencias &lt;a href="http://www.codeplex.com/unity" target="_blank"&gt;Unity&lt;/a&gt;. Una de las preguntas de los asistentes fue sobre si &lt;a href="http://www.codeplex.com/unity" target="_blank"&gt;unity&lt;/a&gt; siempre crea nuevas instancias para los tipos registrados y como podría indicarle que utilice siempre la misma (lo que se conoce como el patrón &lt;a href="http://es.wikipedia.org/wiki/Singleton" target="_blank"&gt;singleton&lt;/a&gt;). Al momento de la reunión conteste que por omisión Unity crea una nueva instancia cada que resuelve un tipo, pero que sí era posible indicar un comportamiento distinto, sin embargo no recordé la manera exacta para ello. Bueno pues aquí la respuesta.&lt;/p&gt;  &lt;p&gt;Al registrar un tipo con el método registerType&amp;lt;TFrom, TTo&amp;gt; podemos pasarle un LifetimeManager el cual será encargado de manejar el tiempo de vida de las instancias resueltas por el contenedor. Podríamos crear nuestro propio LifetimeManager, pero (para el caso del patrón singleton) unity ya cuenta con uno del tipo ContainerControlledLifetimeManager.&lt;/p&gt;  &lt;p&gt;Así que lo único que necesitamos para que nuestro contenedor implemente el patrón &lt;a href="http://es.wikipedia.org/wiki/Singleton" target="_blank"&gt;singleton&lt;/a&gt; al momento de resolver nuestro tipo es pasarle una instancia de la clase ContainerControlledLifetimeManager. Utilizando el mismo ejemplo de la reunión, podríamos suponer que necesitamos que nuestro INotificationService sea siempre la misma instancia para todos los componentes que requieran usarlo. Entonces el código donde registramos nuestro tipo quedaría  así:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="background: none repeat scroll 0% 0% rgb(30, 30, 30);color:white;" &gt;container.RegisterType&amp;lt;&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% rgb(30, 30, 30); color: rgb(104, 151, 187);"&gt;INotificationService&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% rgb(30, 30, 30);color:white;" &gt;, &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% rgb(30, 30, 30); color: rgb(255, 198, 109);"&gt;NotificationServiceWithTemplates&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% rgb(30, 30, 30);color:white;" &gt;&amp;gt;(&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% rgb(30, 30, 30); color: rgb(204, 120, 50);"&gt;&lt;br /&gt; new &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% rgb(30, 30, 30); color: rgb(255, 198, 109);"&gt;ContainerControlledLifetimeManager&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% rgb(30, 30, 30);color:white;" &gt;());&lt;/span&gt;&lt;/pre&gt;Con esto logramos el patrón singleton con unity.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-6939494833529527525?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/6939494833529527525/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=6939494833529527525' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6939494833529527525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6939494833529527525'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/03/singleton-con-unity.html' title='Singleton con Unity'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-5510735736478394228</id><published>2010-03-25T22:00:00.000-07:00</published><updated>2010-03-25T22:11:54.902-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unity'/><category scheme='http://www.blogger.com/atom/ns#' term='TJNET'/><category scheme='http://www.blogger.com/atom/ns#' term='IoC'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Inversión de Control - IoC</title><content type='html'>&lt;p&gt;El día de ayer (Miércoles 24 de Marzo 2010) fue la &lt;a href="http://www.tjnet.org/Eventos/1920.aspx" target="_blank"&gt;Reunión 33&lt;/a&gt; de la comunidad &lt;a href="http://tjnet.org" target="_blank"&gt;TJ.NET&lt;/a&gt; donde presenté el tema “&lt;a href="http://es.wikipedia.org/wiki/Inversi%C3%B3n_de_Control" target="_blank"&gt;Inversión de control (IoC)&lt;/a&gt;”. La reunión se llevo a cabo en las instalaciones del &lt;a href="http://www.tectijuana.mx/" target="_blank"&gt;Instituto Tecnológico de Tijuana&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;En la reunión presenté una introducción a lo que se refiere el principio IoC; con ejemplos como: el usar eventos en nuestros componentes para la interfaz de usuario y el utilizar un Contenedor de dependencias (IoC Container) para realizar una Inversión de control aplicando el patrón de diseño “&lt;a href="http://es.wikipedia.org/wiki/Inyecci%C3%B3n_de_dependencias" target="_blank"&gt;Inyección de dependencias&lt;/a&gt;”. Como ejemplo se refactorizó una aplicación Web ASP.NET para usar un IoC Container (&lt;a href="http://unity.codeplex.com/" target="_blank"&gt;Unity&lt;/a&gt; en este caso). La presentación que fue grabada y el material (diapositivas y archivos) pueden ser descargados desde la &lt;a href="http://www.tjnet.org/Eventos/1920.aspx" target="_blank"&gt;página del evento en la comunidad&lt;/a&gt;.&lt;/p&gt; &lt;object id="scPlayer" height="498" width="640"&gt; &lt;param name="movie" value="http://content.screencast.com/users/gfloresr/folders/Default/media/5551160a-a852-43a6-94c4-f6e9ee2e7c5c/TJNET-IoC-MarioCornejo_controller.swf"&gt; &lt;param name="quality" value="high"&gt; &lt;param name="bgcolor" value="#FFFFFF"&gt; &lt;param name="flashVars" value="thumb=http://content.screencast.com/users/gfloresr/folders/Default/media/5551160a-a852-43a6-94c4-f6e9ee2e7c5c/FirstFrame.png&amp;amp;containerwidth=640&amp;amp;containerheight=498&amp;amp;showstartscreen=true&amp;amp;showendscreen=true&amp;amp;loop=false&amp;amp;autostart=false&amp;amp;color=000000,000000&amp;amp;thumb=FirstFrame.png&amp;amp;thumbscale=45&amp;amp;content=http://content.screencast.com/users/gfloresr/folders/Default/media/5551160a-a852-43a6-94c4-f6e9ee2e7c5c/TJNET-IoC-MarioCornejo.mp4"&gt; &lt;param name="allowFullScreen" value="true"&gt; &lt;param name="scale" value="showall"&gt; &lt;param name="allowScriptAccess" value="always"&gt; &lt;param name="base" value="http://content.screencast.com/users/gfloresr/folders/Default/media/5551160a-a852-43a6-94c4-f6e9ee2e7c5c/"&gt;  &lt;embed src="http://content.screencast.com/users/gfloresr/folders/Default/media/5551160a-a852-43a6-94c4-f6e9ee2e7c5c/TJNET-IoC-MarioCornejo_controller.swf" quality="high" bgcolor="#FFFFFF" type="application/x-shockwave-flash" allowscriptaccess="always" flashvars="thumb=http://content.screencast.com/users/gfloresr/folders/Default/media/5551160a-a852-43a6-94c4-f6e9ee2e7c5c/FirstFrame.png&amp;amp;containerwidth=640&amp;amp;containerheight=498&amp;amp;showstartscreen=true&amp;amp;showendscreen=true&amp;amp;loop=false&amp;amp;autostart=false&amp;amp;color=000000,000000&amp;amp;thumb=FirstFrame.png&amp;amp;thumbscale=45&amp;amp;content=http://content.screencast.com/users/gfloresr/folders/Default/media/5551160a-a852-43a6-94c4-f6e9ee2e7c5c/TJNET-IoC-MarioCornejo.mp4" allowfullscreen="true" base="http://content.screencast.com/users/gfloresr/folders/Default/media/5551160a-a852-43a6-94c4-f6e9ee2e7c5c/" scale="showall" height="498" width="640"&gt; &lt;/object&gt;  &lt;br /&gt;  &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;  &lt;h3&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&lt;font face="Verdana"&gt;&lt;font size="2"&gt;Fotos&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&amp;#160;&lt;iframe style="padding-bottom: 0pt; background-color: rgb(252,252,252); padding-left: 0pt; width: 98px; padding-right: 0pt; height: 115px; padding-top: 0pt" title="Preview" marginheight="0" src="http://cid-b4329e20a9381067.skydrive.live.com/embedicon.aspx/Pictures/Fotos%20de%20Eventos%20TJNET/Fotos%20R33" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt; &lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;                     &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;  &lt;h3&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&lt;font size="2" face="Verdana"&gt;Presentación y archivos&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&amp;#160;&lt;iframe style="padding-bottom: 0pt; background-color: rgb(252,252,252); padding-left: 0pt; width: 98px; padding-right: 0pt; height: 115px; padding-top: 0pt" title="Preview" marginheight="0" src="http://cid-b4329e20a9381067.skydrive.live.com/embedicon.aspx/Eventos%20TJNET/33ra.%20Reuni%c3%b3n" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt; &lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span&gt;&lt;span class="Event_FullDescription"&gt;&lt;span class="Event_FullDescription"&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-5510735736478394228?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/5510735736478394228/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=5510735736478394228' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5510735736478394228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5510735736478394228'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/03/inversion-de-control-ioc.html' title='Inversión de Control - IoC'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-540595199947162561</id><published>2010-02-11T20:45:00.003-08:00</published><updated>2010-02-11T21:00:03.210-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MongoDB'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='base de datos'/><title type='text'>Iniciando con MongoDB desde .Net</title><content type='html'>&lt;p&gt;En el &lt;a href="http://www.developeando.com/2010/02/iniciando-con-mongodb.html" target="_blank"&gt;post anterior&lt;/a&gt; mostré como iniciar con &lt;a href="http://www.mongodb.org/" target="_blank"&gt;mongoDB&lt;/a&gt; utilizando las herramientas que obtenemos al descargar la base de datos. Ahora quiero mostrar las mismas operaciones pero desde .Net (específicamente C#). Para esto es necesario descargar el &lt;a href="http://github.com/samus/mongodb-csharp" target="_blank"&gt;driver&lt;/a&gt; para hablar con mongo desde .net&lt;/p&gt;  &lt;p&gt;Para abrir la conexión a la base de datos debo crear una instancia de la clase MongoDB.Driver.Mongo, llamar el método Connect y después hacer un getDB con el nombre de la base de datos a la que quiero conectarme. Tomando el ejemplo anterior de la libreta de direcciones, el código queda así:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;mongo = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Mongo&lt;/span&gt;();&lt;br /&gt;mongo.Connect();&lt;br /&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;db = mongo.getDB(&lt;span style="color: rgb(163, 21, 21);"&gt;"AddressBook"&lt;/span&gt;);&lt;/pre&gt;&lt;p&gt;una vez conectado a la base de datos obtengo una referencia a mi colección de documentos llamada “Contacts” (similar al concepto de tabla en una base de datos relacional).&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;contacts = db.GetCollection(&lt;span style="color: rgb(163, 21, 21);"&gt;"Contacts"&lt;/span&gt;);&lt;/pre&gt;&lt;p&gt;Ahora para insertar documentos creamos instancias de la clase MongoDB.Driver.Document (el cual es básicamente un diccionario de datos), le damos valores y lo insertamos a nuestra colección de contactos; como en el post anterior inserto 2 documentos a nuestra colección:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;mario = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Document&lt;/span&gt;();&lt;br /&gt;mario[&lt;span style="color: rgb(163, 21, 21);"&gt;"Name"&lt;/span&gt;] = &lt;span style="color: rgb(163, 21, 21);"&gt;"Mario"&lt;/span&gt;;&lt;br /&gt;mario[&lt;span style="color: rgb(163, 21, 21);"&gt;"Phone"&lt;/span&gt;] = &lt;span style="color: rgb(163, 21, 21);"&gt;"1234567"&lt;/span&gt;;&lt;br /&gt;contacts.Insert(mario);&lt;br /&gt;&lt;br /&gt;contacts.Insert(new Document()&lt;br /&gt;  .Append("Name", "Humberto")&lt;br /&gt;  .Append("Phone", "5555555")&lt;br /&gt;);&lt;/pre&gt;&lt;p&gt;Puede observarse dos formas de crear documentos. Una vez teniendo dos contactos (Mario y Humberto). Voy a actualizar al contacto con el nombre “Mario”. Aprovechando que estoy usando una base de datos no relacional, cambiaré las campos del documento, para ello utilizo el método Update de la colección contacts pasando como primer parámetro  el nuevo documento y como segundo parámetro un documento que me sirve como selector&lt;/p&gt;&lt;pre class="code"&gt;contacts.Update(&lt;br /&gt;  &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Document&lt;/span&gt;()&lt;br /&gt;      .Append(&lt;span style="color: rgb(163, 21, 21);"&gt;"FirstName"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"Mario"&lt;/span&gt;)&lt;br /&gt;      .Append(&lt;span style="color: rgb(163, 21, 21);"&gt;"LastName"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"Cornejo"&lt;/span&gt;)&lt;br /&gt;      .Append(&lt;span style="color: rgb(163, 21, 21);"&gt;"Phone"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"1234567"&lt;/span&gt;)&lt;br /&gt;  , &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Document&lt;/span&gt;()&lt;br /&gt;      .Append(&lt;span style="color: rgb(163, 21, 21);"&gt;"Name"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"Mario"&lt;/span&gt;)       &lt;br /&gt;);&lt;/pre&gt;&lt;p&gt;Para hacer solo la actualización del campo teléfono del contacto con el nombre “Humberto” puedo hacer lo siguiente: &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;humberto = contacts.FindOne(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Document&lt;/span&gt;().Append(&lt;span style="color: rgb(163, 21, 21);"&gt;"Name"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"Humberto"&lt;/span&gt;));&lt;br /&gt;humberto[&lt;span style="color: rgb(163, 21, 21);"&gt;"Phone"&lt;/span&gt;] = &lt;span style="color: rgb(163, 21, 21);"&gt;"4444444"&lt;/span&gt;;&lt;br /&gt;contacts.Update(humberto);&lt;/pre&gt;Aquí utilice el mismo método Update, pero solo le pase como parámetro el documento actualizado. Como se puede ver, la forma de realizar las operaciones desde C# es muy similar a como lo haríamos desde la consola usando la aplicación Mongo.exe&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-540595199947162561?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/540595199947162561/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=540595199947162561' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/540595199947162561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/540595199947162561'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/02/iniciando-con-mongodb-desde-net.html' title='Iniciando con MongoDB desde .Net'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2136697301369107848</id><published>2010-02-03T23:31:00.001-08:00</published><updated>2010-02-03T23:31:44.143-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MongoDB'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='AltNet5'/><category scheme='http://www.blogger.com/atom/ns#' term='base de datos'/><title type='text'>Iniciando con MongoDB</title><content type='html'>&lt;p&gt;Recientemente he empezado a jugar con la base de datos no relacional &lt;a href="http://www.mongodb.org" target="_blank"&gt;MongoDB&lt;/a&gt;, grabe un mini-screencast donde muestro la características básicas de esta base de datos orientada a documentos.&lt;/p&gt; &lt;object id="scPlayer" class="embeddedObject" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="600" height="400"&gt;&lt;param name="movie" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/0017c070-30bc-4f24-a5ff-b8999d7e86b6/jingswfplayer.swf"&gt;&lt;/param&gt;&lt;param name="quality" value="high"&gt;&lt;/param&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;/param&gt;&lt;param name="flashVars" value="containerwidth=600&amp;amp;containerheight=400&amp;amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/0017c070-30bc-4f24-a5ff-b8999d7e86b6/FirstFrame.jpg&amp;amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/0017c070-30bc-4f24-a5ff-b8999d7e86b6/MongoDB1_es.swf&amp;amp;blurover=false"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="scale" value="showall"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;param name="base" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/0017c070-30bc-4f24-a5ff-b8999d7e86b6/"&gt;&lt;/param&gt;&lt;embed id="scPlayerFF" class="embeddedObject" src="http://content.screencast.com/users/mhcornejo/folders/Jing/media/0017c070-30bc-4f24-a5ff-b8999d7e86b6/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="600" height="400" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=600&amp;containerheight=400&amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/0017c070-30bc-4f24-a5ff-b8999d7e86b6/FirstFrame.jpg&amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/0017c070-30bc-4f24-a5ff-b8999d7e86b6/MongoDB1_es.swf&amp;blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/mhcornejo/folders/Jing/media/0017c070-30bc-4f24-a5ff-b8999d7e86b6/" scale="showall"&gt;&lt;/embed&gt; &lt;/object&gt;  &lt;p&gt;También puedes ver el &lt;a href="http://screencast.com/t/ZDU1OTli" target="_blank"&gt;video&lt;/a&gt; directamente desde &lt;a href="http://www.screencast.com"&gt;www.screencast.com&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2136697301369107848?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2136697301369107848/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2136697301369107848' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2136697301369107848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2136697301369107848'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2010/02/iniciando-con-mongodb.html' title='Iniciando con MongoDB'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2840349173438363773</id><published>2009-12-21T17:30:00.001-08:00</published><updated>2011-11-08T09:32:32.427-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LinqToSql'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Compartir DataContext por cada HTTP Request</title><content type='html'>Trabajando en proyectos donde, por petición especifica del cliente, debo usar LinqToSql para mi acceso a datos. Donde además se me ha pedido usar las entidades generadas por LinqToSql&amp;nbsp; como mis entidades de negocio. Al abstraer mi acceso a datos con repositorios, Esto con la finalidad de poder hacer pruebas unitarias en mi capa de servicios, me encontré con la necesidad de compartir el DataContext a través de mis repositorios, en si lo que necesitaba era tener un solo DataContext por cada petición HTTP. &lt;br /&gt;Para ello mis repositorios reciben en el constructor un IDataContextFactory la cual será la encargada de pasarle el datacontext a los repositorios&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;public interface &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #6897bb;"&gt;IDataContextFactory&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;&amp;lt;T&amp;gt; &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;where &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;T: &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #ffc66d;"&gt;DataContext&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;, &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;new&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;()&lt;br /&gt;{                                                                  &lt;br /&gt;    T GetCurrentDataContext();                                     &lt;br /&gt;    &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;void &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;DisposeCurrentDataContext();                              &lt;br /&gt;}&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;                                                                  &lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Así mis repositorios no necesitan saber de donde viene el datacontext. Aquí esta la implementación de esta interfaz para tener un datacontext por request&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;public class &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #ffc66d;"&gt;WebDataContextFactory&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;&amp;lt;T&amp;gt;: &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #6897bb;"&gt;IDataContextFactory&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;&amp;lt;T&amp;gt; &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;where &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;T : &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #ffc66d;"&gt;DataContext&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;, &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;new&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;()&lt;br /&gt;{                                                                                         &lt;br /&gt;    &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;public &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;T GetCurrentDataContext()                                                      &lt;br /&gt;    {                                                                                     &lt;br /&gt;        &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;var &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;dataContext = &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #ffc66d;"&gt;HttpContext&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;.Current.Items[&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;typeof&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;(T)] &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;as &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;T;                      &lt;br /&gt;        &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;if &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;(dataContext == &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;null&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;)                                                          &lt;br /&gt;        {                                                                                 &lt;br /&gt;            dataContext = &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;T();                                                        &lt;br /&gt;            &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #ffc66d;"&gt;HttpContext&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;.Current.Items[&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;typeof&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;(T)] = dataContext;                           &lt;br /&gt;        }                                                                                 &lt;br /&gt;                                                                                          &lt;br /&gt;        &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;return &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;dataContext;                                                               &lt;br /&gt;    }                                                                                     &lt;br /&gt;                                                                                          &lt;br /&gt;    &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;public void &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;DisposeCurrentDataContext()                                               &lt;br /&gt;    {                                                                                     &lt;br /&gt;        &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;var &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;dataContext = &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #ffc66d;"&gt;HttpContext&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;.Current.Items[&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;typeof&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;(T)] &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;as &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;T;                      &lt;br /&gt;        &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;if &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;(dataContext != &lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: #cc7832;"&gt;null&lt;/span&gt;&lt;span style="background: none repeat scroll 0% 0% black; color: white;"&gt;)                                                          &lt;br /&gt;            dataContext.Dispose();                                                        &lt;br /&gt;    }                                                                                     &lt;br /&gt;}                                                                                         &lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;lo que hago es guardar el datacontext dentro del diccionario Items del actual HttpContext, el cual esta vivo solo para ese request y se puede utilizar el evento request end del HttpAplication para hacer dispose del datacontext a través del IDataContextFactory&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2840349173438363773?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2840349173438363773/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2840349173438363773' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2840349173438363773'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2840349173438363773'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/12/compartir-datacontext-por-cada-http.html' title='Compartir DataContext por cada HTTP Request'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2928514092439414003</id><published>2009-12-01T18:53:00.001-08:00</published><updated>2009-12-01T19:02:07.497-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FluentValidation'/><category scheme='http://www.blogger.com/atom/ns#' term='Unit Test'/><category scheme='http://www.blogger.com/atom/ns#' term='AltNet5'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>TDD con Fluent Validation Parte 2</title><content type='html'>&lt;p&gt;En el &lt;a href="http://www.developeando.com/2009/11/tdd-con-fluent-validation.html" target="_blank"&gt;post anterior&lt;/a&gt; (screencast) mostré como escribir las pruebas para un validador que usa la librería &lt;a href="http://fluentvalidation.codeplex.com" target="_blank"&gt;FluentValidation&lt;/a&gt;, debido a que se me acababan los 5 minutos, solo mostré las pruebas. en esta ocasión muestro como escribir el código para satisfacer dichas pruebas, el cual es muy simple. el screencast dura solo 2 minutos&lt;/p&gt; &lt;object class="embeddedObject" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="600" height="400"&gt;&lt;param name="movie" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/c4362b55-2810-42cc-81cd-ab65c577b7c7/jingswfplayer.swf"&gt;&lt;/param&gt;&lt;param name="quality" value="high"&gt;&lt;/param&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;/param&gt;&lt;param name="flashVars" value="containerwidth=600&amp;amp;containerheight=400&amp;amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/c4362b55-2810-42cc-81cd-ab65c577b7c7/FirstFrame.jpg&amp;amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/c4362b55-2810-42cc-81cd-ab65c577b7c7/TDD_Fluent_Validation_P2_ES.swf&amp;amp;blurover=false"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="scale" value="showall"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;param name="base" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/c4362b55-2810-42cc-81cd-ab65c577b7c7/"&gt;&lt;/param&gt;&lt;embed class="embeddedObject" src="http://content.screencast.com/users/mhcornejo/folders/Jing/media/c4362b55-2810-42cc-81cd-ab65c577b7c7/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="600" height="400" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=600&amp;containerheight=400&amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/c4362b55-2810-42cc-81cd-ab65c577b7c7/FirstFrame.jpg&amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/c4362b55-2810-42cc-81cd-ab65c577b7c7/TDD_Fluent_Validation_P2_ES.swf&amp;blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/mhcornejo/folders/Jing/media/c4362b55-2810-42cc-81cd-ab65c577b7c7/" scale="showall"&gt;&lt;/embed&gt; &lt;/object&gt;  &lt;p&gt;&lt;a href="http://screencast.com/t/ZGM4NmVhY" target="_blank"&gt;aquí&lt;/a&gt; el link para verlo desde &lt;a href="http://www.jingproject.com/" target="_blank"&gt;jing&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2928514092439414003?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2928514092439414003/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2928514092439414003' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2928514092439414003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2928514092439414003'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/12/tdd-con-fluent-validation-parte-2.html' title='TDD con Fluent Validation Parte 2'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-3216871743984303465</id><published>2009-11-21T17:31:00.001-08:00</published><updated>2009-11-21T17:32:14.240-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FluentValidation'/><category scheme='http://www.blogger.com/atom/ns#' term='Unit Test'/><category scheme='http://www.blogger.com/atom/ns#' term='AltNet5'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Moq'/><title type='text'>TDD con Fluent Validation</title><content type='html'>&lt;p&gt;En este mini-screencast (5 min) muestro como escribir las pruebas unitarias para un validador que será escrito utilizando la librearía &lt;a href="http://fluentvalidation.codeplex.com/" target="_blank"&gt;FluentValidation&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;object class="embeddedObject" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="600" height="400"&gt;&lt;param name="movie" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/507b1d6a-005d-41bd-bada-c17430d69bdd/jingswfplayer.swf"&gt;&lt;/param&gt;&lt;param name="quality" value="high"&gt;&lt;/param&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;/param&gt;&lt;param name="flashVars" value="containerwidth=600&amp;amp;containerheight=400&amp;amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/507b1d6a-005d-41bd-bada-c17430d69bdd/FirstFrame.jpg&amp;amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/507b1d6a-005d-41bd-bada-c17430d69bdd/tdd_fluent_validator_es.swf&amp;amp;blurover=false"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="scale" value="showall"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;param name="base" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/507b1d6a-005d-41bd-bada-c17430d69bdd/"&gt;&lt;/param&gt;&lt;embed class="embeddedObject" src="http://content.screencast.com/users/mhcornejo/folders/Jing/media/507b1d6a-005d-41bd-bada-c17430d69bdd/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="600" height="400" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=600&amp;containerheight=400&amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/507b1d6a-005d-41bd-bada-c17430d69bdd/FirstFrame.jpg&amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/507b1d6a-005d-41bd-bada-c17430d69bdd/tdd_fluent_validator_es.swf&amp;blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/mhcornejo/folders/Jing/media/507b1d6a-005d-41bd-bada-c17430d69bdd/" scale="showall"&gt;&lt;/embed&gt; &lt;/object&gt;&lt;/p&gt;  &lt;p&gt;Para ver el video desde el sitio de &lt;a href="http://www.jingproject.com/" target="_blank"&gt;jing&lt;/a&gt; haz clic &lt;a href="http://screencast.com/t/YjRjOTA3NmYt" target="_blank"&gt;aquí&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-3216871743984303465?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/3216871743984303465/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=3216871743984303465' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3216871743984303465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3216871743984303465'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/11/tdd-con-fluent-validation.html' title='TDD con Fluent Validation'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2089903943703281692</id><published>2009-10-27T11:03:00.001-08:00</published><updated>2009-10-27T11:03:43.943-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Munq'/><category scheme='http://www.blogger.com/atom/ns#' term='IoC'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='AltNet5'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Munq - Inversión de Control para ASP.NET MVC</title><content type='html'>&lt;p&gt;Buscando un contenedor de inversión de control (IoC Container en ingles) ligero para utilizar en una aplicación ASP.NET MVC me encontré con &lt;a href="http://munq.codeplex.com" target="_blank"&gt;Munq&lt;/a&gt; el cual esta escrito a partir del código de &lt;a href="http://funq.codeplex.com/" target="_blank"&gt;Funq&lt;/a&gt;. Me pareció muy fácil de configurar así que grabe un pequeño screencast (4 min), usando &lt;a href="http://www.jingproject.com" target="_blank"&gt;jing&lt;/a&gt;, en el cual muestro como configurarlo para usarlo con la aplicación que crea la platilla de nuevo proyecto ASP.NET MVC 1 en Visual Studio.&lt;/p&gt; &lt;object class="embeddedObject" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="600" height="400"&gt;&lt;param name="movie" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/d0260139-b9a6-4887-83c4-92ca5d658804/jingswfplayer.swf"&gt;&lt;/param&gt;&lt;param name="quality" value="high"&gt;&lt;/param&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;/param&gt;&lt;param name="flashVars" value="containerwidth=600&amp;amp;containerheight=400&amp;amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/d0260139-b9a6-4887-83c4-92ca5d658804/FirstFrame.jpg&amp;amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/d0260139-b9a6-4887-83c4-92ca5d658804/Munq_es.swf&amp;amp;blurover=false&amp;amp;advseek=true"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="scale" value="showall"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;param name="base" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/d0260139-b9a6-4887-83c4-92ca5d658804/"&gt;&lt;/param&gt;&lt;embed class="embeddedObject" src="http://content.screencast.com/users/mhcornejo/folders/Jing/media/d0260139-b9a6-4887-83c4-92ca5d658804/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="600" height="400" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=600&amp;containerheight=400&amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/d0260139-b9a6-4887-83c4-92ca5d658804/FirstFrame.jpg&amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/d0260139-b9a6-4887-83c4-92ca5d658804/Munq_es.swf&amp;blurover=false&amp;advseek=true" allowFullScreen="true" base="http://content.screencast.com/users/mhcornejo/folders/Jing/media/d0260139-b9a6-4887-83c4-92ca5d658804/" scale="showall"&gt;&lt;/embed&gt; &lt;/object&gt;  &lt;p&gt;Para ver directamente desde el sitio de &lt;a href="http://www.jingproject.com" target="_blank"&gt;jing&lt;/a&gt; haz clic &lt;a href="http://screencast.com/t/XB25E93n" target="_blank"&gt;aquí&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2089903943703281692?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2089903943703281692/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2089903943703281692' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2089903943703281692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2089903943703281692'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/10/munq-inversion-de-control-para-aspnet.html' title='Munq - Inversión de Control para ASP.NET MVC'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-4642821757632923193</id><published>2009-10-21T23:23:00.001-07:00</published><updated>2009-10-22T10:15:11.693-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Test'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>TDD ¿Por qué escribir primero las pruebas?</title><content type='html'>&lt;p&gt;Hace poco leí el blog post de &lt;a href="http://ebersys.blogspot.com/" target="_blank"&gt;Eber Irigoyen&lt;/a&gt; donde escribe sobre &lt;a href="http://ebersys.blogspot.com/2009/10/duct-tape-programming-elegant-code.html" target="_blank"&gt;duct tape programming&lt;/a&gt;. Lo que me llamo la atención en ese post es que Eber mencionó que al escribir pruebas, estas no las hace antes de escribir el código necesario para que las pruebas pasen e incluso menciona que la idea de escribir la prueba primero la considera algo tonta (no son sus palabras exactas pero es la idea). En lo personal la idea de escribir la prueba antes del código lo considero como una buena practica y no pensaría que es algo tonto.&lt;/p&gt;  &lt;p&gt;Muchas de las veces cuando se me solicita realizar un nuevo programa o agregar funcionalidad a uno ya existente primero se realiza una entrevista con el usuario final, analista de negocio o cliente (de ahora en adelante lo llamaré cliente) que solicita la funcionalidad. Para que ahí explique a detalle que es lo que necesita. En ocasiones al cliente se le dificulta expresar que es lo que realmente necesita y eso se debe en gran parte porque el tampoco esta seguro que es lo que realmente necesita.&lt;/p&gt;  &lt;p&gt;He notado que esto sucede principalmente cuando el cliente, al empezar a explicar el problema y lo que desea lograr con la nueva funcionalidad, esta pensando en la solución que le ayudará a resolver su problema. Inicia explicando como es que ve su solución en lugar de explicar el problema o lo que quiere lograr con ello. En ocasiones se empieza a discutir la implementación de esa solución y que problemas pudiéramos encontrar, después se discute como es que se podría ayudar a resolver esos problemas. Así la discusión puede continuar centrándose en como resolver los problemas de una posible solución que pudiera o no ser la ideal.&lt;/p&gt;  &lt;p&gt;Si el desarrollo se centra en hacer que la posible solución funcione, se corre el riesgo que al terminar el desarrollo, esta no cumpla con las expectativas del cliente, ya que lo que se tomo en cuenta para desarrollarla fue la posible solución en lugar de lograr que el problema inicial del cliente se resolviera. Esto hace que el cliente se de cuenta que la solución no le sirve del todo pero el desarrollador siente que cumplió porque hizo que funcionara lo que le pidieron.&lt;/p&gt;  &lt;p&gt;Cuando el cliente se centra primero en explicar el problema y en especificar lo que espera lograr, en lugar de pensar en la posible solución. Es entonces cuando yo como profesional puedo trabajar en un programa que resuelva su problema y logre lo que él espera.&lt;/p&gt;  &lt;p&gt;Del mismo modo cuando el desarrollador inicia escribiendo el código que resuelva un problema sin especificar antes que es lo que quiere lograr con ello. Es posible que termine escribiendo código que no va a necesitar. Esto es porque se centra en escribir una solución robusta en lugar de solo resolver el problema.&lt;/p&gt;  &lt;p&gt;Por eso que pienso que el escribir lo que esperamos del código, como una prueba unitaria, antes de escribir la implementación nos da la ventaja de centrarnos en lo que realmente es importante: cumplir con al expectativa. Y no tanto en hacer que nuestra posible solución funcione. De igual forma ayuda a no escribir código que posiblemente no se necesite, ya que la prioridad es hacer que la prueba unitaria (especificación) pase.&lt;/p&gt;  &lt;p&gt;Considero que es benéfico que al iniciar el desarrollo de nueva funcionalidad primero se especifiquen las expectativas que se tienen sobre ella y después se evalúe en base a esas especificaciones. Las expectativas se escriben usando pruebas unitarias y es por eso que me gusta que las pruebas se escriban primero. &lt;/p&gt;  &lt;p&gt;El &lt;a href="http://www.developeando.com/2009/07/tdd-desarrollo-guiado-por-pruebas.html" target="_blank"&gt;desarrollo guidado por pruebas&lt;/a&gt; o TDD (Test Driven Development) no solo se trata de las pruebas. TDD es una tarea de diseño.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-4642821757632923193?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/4642821757632923193/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=4642821757632923193' title='6 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4642821757632923193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4642821757632923193'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/10/tdd-por-que-escribir-primero-las.html' title='TDD ¿Por qué escribir primero las pruebas?'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-1120498746183451303</id><published>2009-10-09T19:27:00.001-07:00</published><updated>2009-10-27T11:13:55.052-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Basic'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='AltNet5'/><category scheme='http://www.blogger.com/atom/ns#' term='XML Literals'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>VB XML Literals – Parte 3 LinqToXml</title><content type='html'>&lt;p&gt;Siguiendo con la serie de post sobre VB XML Literals en esta ocasión en lugar de copiar y pegar el código utilicé &lt;a href="http://www.jingproject.com/" target="_blank"&gt;Jing&lt;/a&gt; para grabar un screencast de 5 minutos donde explico como buscar dentro de un archivo xml usando LinqToXml en VB XML Literals &lt;/p&gt; &lt;object class="embeddedObject" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="600" height="400"&gt;&lt;param name="movie" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/ff224b9d-6d39-47e7-8300-6c02ee3d9d67/jingswfplayer.swf"&gt;&lt;/param&gt;&lt;param name="quality" value="high"&gt;&lt;/param&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;/param&gt;&lt;param name="flashVars" value="containerwidth=600&amp;amp;containerheight=400&amp;amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/ff224b9d-6d39-47e7-8300-6c02ee3d9d67/FirstFrame.jpg&amp;amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/ff224b9d-6d39-47e7-8300-6c02ee3d9d67/XmlLiterals_LinqToXml.swf&amp;amp;blurover=false&amp;amp;advseek=true"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="scale" value="showall"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;param name="base" value="http://content.screencast.com/users/mhcornejo/folders/Jing/media/ff224b9d-6d39-47e7-8300-6c02ee3d9d67/"&gt;&lt;/param&gt;&lt;embed class="embeddedObject" src="http://content.screencast.com/users/mhcornejo/folders/Jing/media/ff224b9d-6d39-47e7-8300-6c02ee3d9d67/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="600" height="400" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=600&amp;containerheight=400&amp;thumb=http://content.screencast.com/users/mhcornejo/folders/Jing/media/ff224b9d-6d39-47e7-8300-6c02ee3d9d67/FirstFrame.jpg&amp;content=http://content.screencast.com/users/mhcornejo/folders/Jing/media/ff224b9d-6d39-47e7-8300-6c02ee3d9d67/XmlLiterals_LinqToXml.swf&amp;blurover=false&amp;advseek=true" allowFullScreen="true" base="http://content.screencast.com/users/mhcornejo/folders/Jing/media/ff224b9d-6d39-47e7-8300-6c02ee3d9d67/" scale="showall"&gt;&lt;/embed&gt; &lt;/object&gt;  &lt;p&gt;Ver &lt;a href="http://screencast.com/t/vmO7vkxv" target="_blank"&gt;screencast&lt;/a&gt; desde el sitio Jing&lt;/p&gt;  &lt;p&gt;Post Relacionados    &lt;br /&gt;&lt;a href="http://www.developeando.com/2009/10/vb-xml-literals-parte-2.html" target="_blank"&gt;VB XML Literals Parte 2&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://www.developeando.com/2009/09/vb-xml-literals.html" target="_blank"&gt;VB XML Literals Parte 1&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-1120498746183451303?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/1120498746183451303/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=1120498746183451303' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1120498746183451303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1120498746183451303'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/10/vb-xml-literals-parte-3-linqtoxml.html' title='VB XML Literals – Parte 3 LinqToXml'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2079849168180912873</id><published>2009-10-05T21:31:00.002-07:00</published><updated>2009-10-05T21:34:52.352-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='programacion'/><category scheme='http://www.blogger.com/atom/ns#' term='XML Literals'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>VB XML Literals - Parte 2</title><content type='html'>&lt;p&gt;En la &lt;a href="http://www.developeando.com/2009/09/vb-xml-literals.html" target="_blank"&gt;parte 1&lt;/a&gt; de esta serie de posts sobre XML Literals expliqué en el ejemplo como cargar un objeto a partir de un archivo xml. Ahora veré el caso contrario: A partir de un objeto Order creare un archivo xml con la información de la orden. Este es el test con que comprobaré que mi método esta funcionando:&lt;/p&gt;  &lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;TestMethod&lt;/span&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;public void &lt;/span&gt;should_save_order_to_file()&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color:blue;"&gt;var &lt;/span&gt;fileName = &lt;span style="color: rgb(163, 21, 21);"&gt;@"..\..\Order_Temp.xml"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:blue;"&gt;if &lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;File&lt;/span&gt;.Exists(fileName)) &lt;span style="color: rgb(43, 145, 175);"&gt;File&lt;/span&gt;.Delete(fileName);&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:blue;"&gt;var &lt;/span&gt;order = CreateSampleOrder();&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:blue;"&gt;var &lt;/span&gt;orderXmlTasks = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;OrderXmlTasks&lt;/span&gt;();&lt;br /&gt;   orderXmlTasks.SaveToFile(fileName, order);&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(43, 145, 175);"&gt;File&lt;/span&gt;.Exists(fileName).Should().Be.True();&lt;br /&gt;  &lt;br /&gt;   &lt;span style="color:blue;"&gt;var &lt;/span&gt;fileLines = &lt;span style="color: rgb(43, 145, 175);"&gt;File&lt;/span&gt;.ReadAllLines(fileName);&lt;br /&gt;   &lt;span style="color:blue;"&gt;var &lt;/span&gt;expectedLines = CreateExpectedXml();&lt;br /&gt;   &lt;span style="color:blue;"&gt;for &lt;/span&gt;(&lt;span style="color:blue;"&gt;int &lt;/span&gt;i = 0; i &amp;lt; fileLines.Length; i++)&lt;br /&gt;   {&lt;br /&gt;       &lt;span style="color:blue;"&gt;var &lt;/span&gt;line = fileLines[i].Trim();&lt;br /&gt;       line.Should().Be.EqualTo(expectedLines[i]);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Order &lt;/span&gt;CreateSampleOrder()&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Order&lt;br /&gt;   &lt;/span&gt;{&lt;br /&gt;       Id = 321,&lt;br /&gt;       Customer = &lt;span style="color: rgb(163, 21, 21);"&gt;"Peter Griffin"&lt;/span&gt;,&lt;br /&gt;       Items = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;OrderItem&lt;/span&gt;&amp;gt;&lt;br /&gt;       {&lt;br /&gt;           &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;OrderItem &lt;/span&gt;{ ProductId = 3, Quantity = 1, Price = 2.05m, Description = &lt;span style="color: rgb(163, 21, 21);"&gt;"product x" &lt;/span&gt;},&lt;br /&gt;           &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;OrderItem &lt;/span&gt;{ ProductId = 7, Quantity = 4, Price = 3.45m, Description = &lt;span style="color: rgb(163, 21, 21);"&gt;"product y" &lt;/span&gt;},&lt;br /&gt;           &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;OrderItem &lt;/span&gt;{ ProductId = 8, Quantity = 9, Price = 5.50m, Description = &lt;span style="color: rgb(163, 21, 21);"&gt;"product z" &lt;/span&gt;},&lt;br /&gt;       }&lt;br /&gt;   };&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;public string&lt;/span&gt;[] CreateExpectedXml()&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color:blue;"&gt;var &lt;/span&gt;xml = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;gt;();&lt;br /&gt;  &lt;br /&gt;   xml.Add(&lt;span style="color: rgb(163, 21, 21);"&gt;"&amp;lt;?xml version=\"1.0\" encoding=\"utf-8\"?&amp;gt;"&lt;/span&gt;);&lt;br /&gt;   xml.Add(&lt;span style="color: rgb(163, 21, 21);"&gt;"&amp;lt;order id=\"321\" xmlns=\"urn:schemas-developeando-com:xmlLiterals\"&amp;gt;"&lt;/span&gt;);&lt;br /&gt;   xml.Add(&lt;span style="color: rgb(163, 21, 21);"&gt;"&amp;lt;customer&amp;gt;Peter Griffin&amp;lt;/customer&amp;gt;"&lt;/span&gt;);&lt;br /&gt;   xml.Add(&lt;span style="color: rgb(163, 21, 21);"&gt;"&amp;lt;items&amp;gt;"&lt;/span&gt;);&lt;br /&gt;   xml.Add(&lt;span style="color: rgb(163, 21, 21);"&gt;"&amp;lt;item productId=\"3\" quantity=\"1\" price=\"2.05\"&amp;gt;product x&amp;lt;/item&amp;gt;"&lt;/span&gt;);&lt;br /&gt;   xml.Add(&lt;span style="color: rgb(163, 21, 21);"&gt;"&amp;lt;item productId=\"7\" quantity=\"4\" price=\"3.45\"&amp;gt;product y&amp;lt;/item&amp;gt;"&lt;/span&gt;);&lt;br /&gt;   xml.Add(&lt;span style="color: rgb(163, 21, 21);"&gt;"&amp;lt;item productId=\"8\" quantity=\"9\" price=\"5.50\"&amp;gt;product z&amp;lt;/item&amp;gt;"&lt;/span&gt;);&lt;br /&gt;   xml.Add(&lt;span style="color: rgb(163, 21, 21);"&gt;"&amp;lt;/items&amp;gt;"&lt;/span&gt;);&lt;br /&gt;   xml.Add(&lt;span style="color: rgb(163, 21, 21);"&gt;"&amp;lt;/order&amp;gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:blue;"&gt;return &lt;/span&gt;xml.ToArray();&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;Lo que hace el test es crear una orden de ejemplo (CreateSampleOrder), escribir los datos de la orden en un archivo xml y después leo el archivo generado y lo comparo con el xml esperado (CreateExpectedXml)&lt;/p&gt;&lt;p&gt;Generar xml  usando XML Literals es tan simple como solo escribir el XML y agregar expresiones donde queremos insertar código. Entonces el código para que la prueba pase queda así:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Public Sub &lt;/span&gt;SaveToFile(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;FileName &lt;span style="color:blue;"&gt;As String&lt;/span&gt;, &lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;Order &lt;span style="color:blue;"&gt;As &lt;/span&gt;Order)&lt;br /&gt;   &lt;span style="color:blue;"&gt;Dim &lt;/span&gt;xml = &lt;span style="color: rgb(100, 100, 185);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(132, 70, 70);"&gt;order &lt;/span&gt;&lt;span style="color: rgb(185, 100, 100);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;=&lt;/span&gt;&lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;&amp;lt;%=&lt;/span&gt; Order.Id &lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;gt;&lt;br /&gt;                 &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(132, 70, 70);"&gt;customer&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;&amp;lt;%=&lt;/span&gt; Order.Customer &lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(132, 70, 70);"&gt;customer&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;gt;&lt;br /&gt;                 &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(132, 70, 70);"&gt;items&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;gt;&lt;br /&gt;                     &lt;/span&gt;&lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;&amp;lt;%=&lt;/span&gt; &lt;span style="color:blue;"&gt;From &lt;/span&gt;item &lt;span style="color:blue;"&gt;In &lt;/span&gt;Order.Items _&lt;br /&gt;                         &lt;span style="color:blue;"&gt;Select &lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(132, 70, 70);"&gt;item&lt;br /&gt;                                    &lt;/span&gt;&lt;span style="color: rgb(185, 100, 100);"&gt;productId&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;=&lt;/span&gt;&lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;&amp;lt;%=&lt;/span&gt; item.ProductId &lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                                     &lt;span style="color: rgb(185, 100, 100);"&gt;quantity&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;=&lt;/span&gt;&lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;&amp;lt;%=&lt;/span&gt; item.Quantity &lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                                     &lt;span style="color: rgb(185, 100, 100);"&gt;price&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;=&lt;/span&gt;&lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;&amp;lt;%=&lt;/span&gt; item.Price &lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;gt;&lt;br /&gt;                                    &lt;/span&gt;&lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;&amp;lt;%=&lt;/span&gt; item.Description &lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                                 &lt;span style="color: rgb(100, 100, 185);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(132, 70, 70);"&gt;item&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;gt; &lt;/span&gt;&lt;span style="background: rgb(255, 254, 191) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(85, 85, 85);"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                  &lt;span style="color: rgb(100, 100, 185);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(132, 70, 70);"&gt;items&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;gt;&lt;br /&gt;             &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(132, 70, 70);"&gt;order&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;gt;&lt;br /&gt;   &lt;/span&gt;xml.Save(FileName)&lt;br /&gt;&lt;span style="color:blue;"&gt;End Sub&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Como se puede apreciar solo declaro una variable y le asigno el  xml, usando expresiones para indicar donde quiero escribir los valores de las propiedades del objeto Order. Para los items utilizo una expresión LINQ para indicar que por cada item agregue un elemento &amp;lt;item&amp;gt; y asigno el valor a los atributos y el valor de la descripción en el texto interno. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2079849168180912873?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2079849168180912873/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2079849168180912873' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2079849168180912873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2079849168180912873'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/10/vb-xml-literals-parte-2.html' title='VB XML Literals - Parte 2'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-3785040949882053136</id><published>2009-09-29T18:42:00.011-07:00</published><updated>2009-09-30T23:06:35.299-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Test'/><category scheme='http://www.blogger.com/atom/ns#' term='TestsEx'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='programacion'/><category scheme='http://www.blogger.com/atom/ns#' term='XML Literals'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>VB XML Literals</title><content type='html'>&lt;p&gt;Desde la versión 9.0 de VB .Net existe una característica llamada XML Literals la cual consiste en poder escribir XML directamente en el código VB y manejar el xml como parte del lenguaje. &lt;br /&gt;&lt;br /&gt;Actualmente cuando en una solución necesito trabajar con XML, donde generalmente hay puros proyectos de C#, también agrego un proyecto en VB.Net solo para el manejo de XML por que se me facilita con XML Literals.  &lt;br /&gt;&lt;br /&gt;Para mostrar como se utiliza XML Literals mostraré un ejemplo (el clásico ejemplo de una orden) el cual consiste en una clase que exporta e importa ordenes a/desde XML.&lt;/p&gt;  &lt;p&gt;Para esto creo una solución con 3 proyectos uno de tipo C# Windows library con el nombre XmlLiteralsExample.Domain el cual contiene las clases Order y OrderItem con esta definición&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;XmlLiteralsExample.Domain&lt;br /&gt;{&lt;br /&gt; &lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Order&lt;br /&gt; &lt;/span&gt;{&lt;br /&gt;     &lt;span style="color:blue;"&gt;public int &lt;/span&gt;Id { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt;     &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Customer { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt;     &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;OrderItem&lt;/span&gt;&amp;gt; Items { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:blue;"&gt;public &lt;/span&gt;Order()&lt;br /&gt;     {&lt;br /&gt;         Items = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;OrderItem&lt;/span&gt;&amp;gt;();&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;OrderItem&lt;br /&gt; &lt;/span&gt;{&lt;br /&gt;     &lt;span style="color:blue;"&gt;public int &lt;/span&gt;ProductId { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt;     &lt;span style="color:blue;"&gt;public int &lt;/span&gt;Quantity { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt;     &lt;span style="color:blue;"&gt;public string &lt;/span&gt;Description { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt;     &lt;span style="color:blue;"&gt;public decimal &lt;/span&gt;Price { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;Ahora agrego el proyecto de tipo VB Class library llamado XmlLiteralsExample.Tasks en el cual agregaré la clase en VB que me ayudará con el XML &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Imports &lt;/span&gt;XmlLiteralsExample.Domain&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;Public Class &lt;/span&gt;OrderXmlTasks&lt;br /&gt; &lt;span style="color:blue;"&gt;Public Function &lt;/span&gt;ReadFromFile(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;FileName &lt;span style="color:blue;"&gt;As String&lt;/span&gt;) &lt;span style="color:blue;"&gt;As &lt;/span&gt;Order&lt;br /&gt;     &lt;span style="color:blue;"&gt;Throw New &lt;/span&gt;NotImplementedException()&lt;br /&gt; &lt;span style="color:blue;"&gt;End Function&lt;br /&gt;&lt;br /&gt; Public Sub &lt;/span&gt;SaveToFile(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;FileName &lt;span style="color:blue;"&gt;As String&lt;/span&gt;)&lt;br /&gt;     &lt;span style="color:blue;"&gt;Throw New &lt;/span&gt;NotImplementedException()&lt;br /&gt; &lt;span style="color:blue;"&gt;End Sub&lt;br /&gt;&lt;br /&gt; Public Function &lt;/span&gt;FindOrderItem(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;FileName &lt;span style="color:blue;"&gt;As String&lt;/span&gt;, _&lt;br /&gt;                               &lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;ProductId &lt;span style="color:blue;"&gt;As Integer&lt;/span&gt;) &lt;span style="color:blue;"&gt;As &lt;/span&gt;OrderItem&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:blue;"&gt;Throw New &lt;/span&gt;NotImplementedException()&lt;br /&gt; &lt;span style="color:blue;"&gt;End Function&lt;br /&gt;&lt;br /&gt;End Class&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_GuIIcTHVIyM/SsQ0QX0LuHI/AAAAAAAAAIY/lbecpWartB0/s1600-h/XmlLiteralsSolution%5B2%5D.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="XmlLiteralsSolution" alt="XmlLiteralsSolution" src="http://lh6.ggpht.com/_GuIIcTHVIyM/SsQ0QySSqzI/AAAAAAAAAIc/4VfB_cc7ymQ/XmlLiteralsSolution_thumb.png?imgmax=800" border="0" height="244" width="208" /&gt;&lt;/a&gt; Y por último agrego un proyecto para las pruebas unitarias en C# llamado XmlLiteralsExample.Tasks.Test en el cual agregaré las pruebas unitarias para nuestra clase OrderXmlTasks y un archivo xml para las pruebas.&lt;/p&gt;&lt;p&gt;El proyecto XmlLiteralsExample.Test tiene referencias al proyecto Domain así como el proyecto XmlLiteralsExample.Tasks.Test tiene referencias a los otros 2 proyectos de la solución&lt;/p&gt;&lt;p&gt;Además el proyecto de prueba incluye una referencia a las extensiones SharpTestsEx&lt;/p&gt;&lt;p&gt;El Archivo Order.xml contiene una orden de prueba&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;xml &lt;/span&gt;&lt;span style="color:red;"&gt;version&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;1.0&lt;/span&gt;" &lt;span style="color:red;"&gt;encoding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;utf-8&lt;/span&gt;" &lt;span style="color:blue;"&gt;?&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;order &lt;/span&gt;&lt;span style="color:red;"&gt;id&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;123&lt;/span&gt;" &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;urn:schemas-developeando-com:xmlLiterals&lt;/span&gt;"&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;customer&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Homer Simpson&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;customer&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;items&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item &lt;/span&gt;&lt;span style="color:red;"&gt;productID&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;1&lt;/span&gt;" &lt;span style="color:red;"&gt;quantity&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;2&lt;/span&gt;" &lt;span style="color:red;"&gt;price&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;1.50&lt;/span&gt;"&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;product desc 1&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item &lt;/span&gt;&lt;span style="color:red;"&gt;productID&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;2&lt;/span&gt;" &lt;span style="color:red;"&gt;quantity&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;4&lt;/span&gt;" &lt;span style="color:red;"&gt;price&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;2.60&lt;/span&gt;"&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;product desc 2&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item &lt;/span&gt;&lt;span style="color:red;"&gt;productID&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;3&lt;/span&gt;" &lt;span style="color:red;"&gt;quantity&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;6&lt;/span&gt;" &lt;span style="color:red;"&gt;price&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;"&lt;span style="color:blue;"&gt;3.80&lt;/span&gt;"&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;product desc 3&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;items&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;order&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;A partir del archivo de prueba (Order.xml) genero el xml schema utilizando la opción del menú XML de VisualStudio y la guardo en el folder del proyecto Tasks y después agrego el archivo al proyecto. Con esto puedo importar el xml namespace en el archivo OrderXmlTasks.vb como si fuera un namespace de .net&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Imports &lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(185, 100, 100);"&gt;xmlns&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(85, 85, 85);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;urn:schemas-developeando-com:xmlLiterals&lt;/span&gt;&lt;span style="color: rgb(85, 85, 85);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Esto me ayudará a que visual studio conozca la estructura de mi xml y así pueda darme opciones a través de intellisense&lt;/p&gt;&lt;p&gt;Ahora que tengo los datos de prueba iniciamos con con la funcionalidad, para ello escribo mi primer test en la clase OrderXmlTasksTest (dentro del proyecto de prueba)&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;TestMethod&lt;/span&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;public void &lt;/span&gt;should_load_order_from_file()&lt;br /&gt;{&lt;br /&gt; &lt;span style="color:blue;"&gt;var &lt;/span&gt;orderXmlTasks = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;OrderXmlTasks&lt;/span&gt;();&lt;br /&gt; &lt;span style="color:blue;"&gt;var &lt;/span&gt;order = orderXmlTasks.ReadFromFile(&lt;span style="color: rgb(163, 21, 21);"&gt;@"C:\..\..\Order.xml"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt; order.Id.Should().Be.EqualTo(123);&lt;br /&gt; order.Customer.Should().Be.EqualTo(&lt;span style="color: rgb(163, 21, 21);"&gt;"Homer Simpson"&lt;/span&gt;);&lt;br /&gt; order.Items.Count.Should().Be.EqualTo(3);         &lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;Ahora el código para pasar esta prueba:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Public Function &lt;/span&gt;ReadFromFile(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;FileName &lt;span style="color:blue;"&gt;As String&lt;/span&gt;) &lt;span style="color:blue;"&gt;As &lt;/span&gt;Order&lt;br /&gt; &lt;span style="color:blue;"&gt;Dim &lt;/span&gt;orderXml = XElement.Load(FileName)&lt;br /&gt;&lt;br /&gt; &lt;span style="color:blue;"&gt;Dim &lt;/span&gt;order = &lt;span style="color:blue;"&gt;New &lt;/span&gt;Order()&lt;br /&gt; &lt;span style="color:blue;"&gt;With &lt;/span&gt;order&lt;br /&gt;     .Id = &lt;a href="mailto:orderXml.@id"&gt;orderXml.&lt;span style="color: rgb(100, 100, 185);"&gt;@&lt;/span&gt;id&lt;br /&gt;&lt;/a&gt;        .Customer = orderXml.&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;lt;&lt;/span&gt;customer&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;gt;&lt;/span&gt;.Value         &lt;br /&gt; &lt;span style="color:blue;"&gt;End With&lt;br /&gt;&lt;br /&gt; For Each &lt;/span&gt;itemXml &lt;span style="color:blue;"&gt;In &lt;/span&gt;orderXml.&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;lt;&lt;/span&gt;items&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;gt;&lt;/span&gt;.&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;lt;&lt;/span&gt;item&lt;span style="color: rgb(100, 100, 185);"&gt;&amp;gt;         &lt;br /&gt;     &lt;/span&gt;&lt;span style="color:blue;"&gt;Dim &lt;/span&gt;item = &lt;span style="color:blue;"&gt;New &lt;/span&gt;OrderItem()&lt;br /&gt;     &lt;span style="color:blue;"&gt;With &lt;/span&gt;item&lt;br /&gt;         .ProductId = &lt;a href="mailto:itemXml.@productID"&gt;itemXml.&lt;span style="color: rgb(100, 100, 185);"&gt;@&lt;/span&gt;productID&lt;br /&gt;&lt;/a&gt;            .Quantity = &lt;a href="mailto:itemXml.@quantity"&gt;itemXml.&lt;span style="color: rgb(100, 100, 185);"&gt;@&lt;/span&gt;quantity&lt;br /&gt;&lt;/a&gt;            .Price = &lt;a href="mailto:itemXml.@price"&gt;itemXml.&lt;span style="color: rgb(100, 100, 185);"&gt;@&lt;/span&gt;price&lt;br /&gt;&lt;/a&gt;            .Description = itemXml.Value&lt;br /&gt;     &lt;span style="color:blue;"&gt;End With&lt;br /&gt;     &lt;/span&gt;order.Items.Add(item)&lt;br /&gt; &lt;span style="color:blue;"&gt;Next&lt;br /&gt;&lt;br /&gt; Return &lt;/span&gt;order&lt;br /&gt;&lt;span style="color:blue;"&gt;End Function&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Ahora explico un poco lo que hace el código; la primer línea carga el xml a un objeto. En este ejemplo uso la clase XElement la cual carga el xml a partir del elemento raíz (en este caso la etiqueta Order). Por lo tanto el objeto orderXml me representa la etiqueta Order del archivo xml. Después creo un objeto order que después lleno con los datos del archivo xml cargados en el objeto orderXml. &lt;/p&gt;&lt;p&gt;En XML Literals  para accesar a los atributos de un elemento xml utilizamos la @ es por eso que podemos ver que de carga en la propiedad Id, del objeto order, el valor del atributo id del elemento order del xml. Después se puede notar que para tener acceso a los elementos hijos solo hace falta escribir las etiquetas tal y como lo haríamos en un archivo xml  y gracias a que importe el namespace xml también tengo intellisense&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_GuIIcTHVIyM/SsQ0RXw_jfI/AAAAAAAAAIg/5BDC072Mtj4/s1600-h/intellisense%5B2%5D.jpg"&gt;&lt;img style="border-width: 0px; display: inline;" title="intellisense" alt="intellisense" src="http://lh4.ggpht.com/_GuIIcTHVIyM/SsQ0RkSJOcI/AAAAAAAAAIk/QEugOhTS160/intellisense_thumb.jpg?imgmax=800" border="0" height="79" width="191" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;de igual forma en una ciclo for each acceso a la colección de items. En este caso acceso al elemento item a través de toda la ruta de elementos hijos. &lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_GuIIcTHVIyM/SsQ0R8va8-I/AAAAAAAAAIo/LdtI3GJe2Rc/s1600-h/intellisense2%5B2%5D.jpg"&gt;&lt;img style="border-width: 0px; display: inline;" title="intellisense2" alt="intellisense2" src="http://lh4.ggpht.com/_GuIIcTHVIyM/SsQ0SaoyW2I/AAAAAAAAAIs/bc67epOPoGY/intellisense2_thumb.jpg?imgmax=800" border="0" height="95" width="211" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Pero además XML literals me permite accesar a  elementos hijos sin tener que seguir la ruta usando tres puntos entre el objeto y la etiqueta.&lt;/p&gt;&lt;p&gt;Para obtener al texto dentro de una etiqueta se utiliza la propiedad Value del objeto XElement. Así es como obtengo el nombre del cliente y la descripción de los ítems.&lt;/p&gt;&lt;p&gt;Bueno este post ya se extendió y tengo que dividirlo, seguiré con el ejemplo en otro post.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-3785040949882053136?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/3785040949882053136/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=3785040949882053136' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3785040949882053136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3785040949882053136'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/09/vb-xml-literals.html' title='VB XML Literals'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_GuIIcTHVIyM/SsQ0QySSqzI/AAAAAAAAAIc/4VfB_cc7ymQ/s72-c/XmlLiteralsSolution_thumb.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-1550703751811547735</id><published>2009-09-17T20:21:00.007-07:00</published><updated>2009-09-17T21:26:28.806-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Test'/><category scheme='http://www.blogger.com/atom/ns#' term='TestsEx'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Moq'/><title type='text'>Sharp Tests Ex</title><content type='html'>Descargue las extensiones para MsTests desarrolladas por &lt;a href="http://fabiomaulo.blogspot.com/"&gt;Fabio Maulo:&lt;/a&gt; "&lt;a href="http://sharptestsex.codeplex.com/"&gt;Sharp Tests Extensions&lt;/a&gt;". La idea de estas extensiones es que tus aserciones en las pruebas sean escritas con mayor fluidez. ademas de que es mas clara la distinción entre el valor esperado y el valor obtenido. Evitando el uso de la clase Assert directamente.&lt;br /&gt;&lt;br /&gt;Un ejemplo de como cambia un test usando estas extensiones&lt;br /&gt;&lt;br /&gt;Test usando MsTest sin extensiones&lt;br /&gt;&lt;br /&gt;&lt;pre class="c-sharp" name="code"&gt;[TestMethod]&lt;br /&gt;public void should_change_password()&lt;br /&gt;{&lt;br /&gt;var username = "username";&lt;br /&gt;var originalPassword = "original";&lt;br /&gt;var newPassword = "newPassword";&lt;br /&gt;&lt;br /&gt;var user = new User { Password = originalPassword };&lt;br /&gt;&lt;br /&gt;mockRepository.Setup(r =&gt; r.GetUser(username))&lt;br /&gt;    .Returns(user);&lt;br /&gt;&lt;br /&gt;bool result = accountService.ChangePassword(&lt;br /&gt;     username, originalPassword, newPassword);&lt;br /&gt;&lt;br /&gt;Assert.IsTrue(result);&lt;br /&gt;Assert.AreEqual(newPassword, user.Password);     &lt;br /&gt;mockRepository.Verify(r =&gt; r.Save());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ahora esta es la misma prueba utilizando &lt;a href="http://sharptestsex.codeplex.com/"&gt;Sharp TextsEx&lt;/a&gt;&lt;br /&gt;&lt;pre class="c-sharp" name="code"&gt;[TestMethod]&lt;br /&gt;public void should_change_password()&lt;br /&gt;{&lt;br /&gt;var username = "username";&lt;br /&gt;var originalPassword = "original";&lt;br /&gt;var newPassword = "newPassword";&lt;br /&gt;&lt;br /&gt;var user = new User { Password = originalPassword };&lt;br /&gt;&lt;br /&gt;mockRepository.Setup(r =&gt; r.GetUser(username))&lt;br /&gt;    .Returns(user);&lt;br /&gt;&lt;br /&gt;bool result = accountService.ChangePassword(&lt;br /&gt;     username, originalPassword, newPassword);&lt;br /&gt;&lt;br /&gt;result.Should().Be.True();&lt;br /&gt;user.Password.Should().Be.EqualTo(newPassword);&lt;br /&gt;mockRepository.Verify(r =&gt; r.Save());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;estas son las lineas que cambian de:&lt;br /&gt;&lt;pre class="c-sharp" name="code"&gt;Assert.IsTrue(result);&lt;br /&gt;Assert.AreEqual(newPassword, user.Password);&lt;/pre&gt;&lt;br /&gt;a&lt;br /&gt;&lt;pre class="c-sharp" name="code"&gt;result.Should().Be.True();&lt;br /&gt;user.Password.Should().Be.EqualTo(newPassword);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Se escribe mas sin embargo queda mas descriptivo cual es la intensión de la prueba ademas de que tenemos la ventaja que intellisense nos ayuda a completar la aserción.&lt;br /&gt;&lt;br /&gt;En lo personal me cuesta un poco acostumbrarme a no ver la clase Assert al final de los metodos, pero debo reconocer que el test es mas claro así.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-1550703751811547735?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/1550703751811547735/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=1550703751811547735' title='4 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1550703751811547735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1550703751811547735'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/09/sharp-tests-ex.html' title='Sharp Tests Ex'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2020345547508852129</id><published>2009-07-28T19:06:00.002-07:00</published><updated>2009-07-28T20:01:22.338-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Test'/><category scheme='http://www.blogger.com/atom/ns#' term='programacion'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>TDD - Desarrollo Guiado Por Pruebas</title><content type='html'>&lt;p&gt;En la &lt;a href="http://www.tjnet.org/Eventos/1860.aspx"&gt;reunión 30&lt;/a&gt; de la comunidad &lt;a href="http://tjnet.org/" target="_blank"&gt;TjNet&lt;/a&gt; estaré presentando el tema TDD (Test Driven Development), el cual es una práctica de programación que consiste en escribir primero las pruebas unitarias, después el código que cumple con las pruebas y refactorizar el código escrito.&lt;/p&gt;&lt;p&gt;La idea principal es que el comportamiento esperado del objeto que estamos probando lo definamos en pruebas y después nos preocupemos por que el objeto cumpla con lo que se definió en las pruebas.&lt;/p&gt;&lt;p&gt;Cabe aclarar que el TDD es una actividad del equipo de desarrollo y no del equipo de QA que realiza las pruebas al software. La intención de las pruebas unitarias no es que el equipo de calidad las use para realizar su trabajo. Las pruebas unitarias son para definir el comportamiento del código que vamos escribir, es decir es parte del diseño. Aunque sí aumentan en cierta forma la calidad del código escrito.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Efectos del desarrollo guiado por pruebas&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Algunos de los efectos notables sobre el desarrollo guiado por pruebas es que se evita escribir código que no se utilizará. Ya que se trata de realizar solamente el código necesario para poder satisfacer las pruebas definidas.&lt;/p&gt;&lt;p&gt;Otro efecto que se obtiene al trabajar de esta manera es que como nuestras clases ya no solo van a ser utilizadas por la aplicación, sino también por el código de prueba, esto nos obliga a tener clases débilmente acopladas y que hacen uso de dependencias solo a través de interfaces, independientemente de la implementación. De tal forma que sea fácil utilizar ciertas clases concretas para la aplicación y otras para las pruebas. Para esto es común aplicar el principio de inyección de dependencias.&lt;/p&gt;&lt;p&gt;El mantenimiento del código es más manejable, la confianza en el código mejora, por que las pruebas nos sirven como alerta cuando introducimos código que hace que nuestras pruebas fallen. En lugar de introducir cambios al código sin saber cómo afectan a otras clases del sistema.&lt;/p&gt;&lt;p&gt;El uso del depurador disminuye ya que cuando existe un error en el código es más fácil encontrarlo en las pruebas que corriendo la aplicación en modo debug.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Ciclo de desarrollo&lt;/b&gt;&lt;/p&gt;&lt;p&gt;1. Escribir el comportamiento deseado (requerimiento) a manera de prueba unitaria, Este paso fuerza al programador a tomar la perspectiva de un cliente considerando el código a través de sus interfaces. Obviamente la prueba fallará ya que aun no está escrito el código para satisfacerla.&lt;/p&gt;&lt;p&gt;2. Escribir solo el código necesario para que la prueba pase.&lt;/p&gt;&lt;p&gt;3. Correr las pruebas para confirmar que efectivamente el código escrito cumple con los establecido por las pruebas.&lt;/p&gt;&lt;p&gt;4. Refactorizar el código, para eliminar código duplicado y dejarlo de tal forma que sea fácil hacerle modificaciones en el futuro.&lt;/p&gt;&lt;p&gt;5. Verifica que las pruebas no fallen después de la refactorización.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Conclusión&lt;/b&gt;&lt;/p&gt;&lt;p&gt;El desarrollo guiado por pruebas no es parte del proceso de calidad de un sistema en desarrollo (aunque si aumenta la calidad del código escrito) sino que forma parte del diseño de cada clase; define el comportamiento esperado de la clase desde el punto de vista del cliente que la usará. &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Los espero en la reunión 30 de la comunidad TjNet.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2020345547508852129?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2020345547508852129/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2020345547508852129' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2020345547508852129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2020345547508852129'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/07/tdd-desarrollo-guiado-por-pruebas.html' title='TDD - Desarrollo Guiado Por Pruebas'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-23643962624856136</id><published>2009-06-17T09:33:00.008-07:00</published><updated>2009-06-17T10:19:46.417-07:00</updated><title type='text'>Agile Programming Coffee Camp</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://tjnet.org/Image.aspx?src=AgileCoffeCamp1.jpg&amp;amp;Height=-1"&gt;&lt;img style="cursor: pointer; width: 313px; height: 157px;" src="http://tjnet.org/Image.aspx?src=AgileCoffeCamp1.jpg&amp;amp;Height=-1" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Tijuana Agile Programming Coffee Camp en el devolada de otay  (el lugar de costumbre) el sábado 4 de Julio, a partir de las 9:00am.&lt;br /&gt;&lt;br /&gt;La idea surgió de una conversación en twitter entre &lt;a href="http://twitter.com/mario_chavez"&gt;@mario_chavez&lt;/a&gt; y &lt;a href="http://twitter.com/FCastellanos"&gt;@fcastellanos&lt;/a&gt; a la que nos sumamos &lt;a href="http://twitter.com/gabo"&gt;@gabo&lt;/a&gt; y &lt;a href="http://twitter.com/mariohcornejo"&gt;yo&lt;/a&gt;. Y como 140 caracteres no es suficiente y varios queremos participar; pues mejor platiquemos sobre el tema tomando café.&lt;br /&gt;&lt;br /&gt;Cualquiera puede participar, es una platica entre colegas, el costo es según el tamaño del café que pidas.&lt;br /&gt;&lt;br /&gt;Si conoces del tema asiste a compartir tus experiencias, y si no, es una buena oportunidad para aprender.&lt;br /&gt;&lt;br /&gt;Mas información (mapas, fotos y Dilbert) en:&lt;br /&gt;&lt;a href="http://tjnet.org/Eventos/1837.aspx"&gt;TjNet &lt;/a&gt;&lt;br /&gt;&lt;a href="http://mario-chavez.blogspot.com/2009/06/agile-coffecamp-tijuana.html"&gt;blog de Mario Chavez&lt;/a&gt;&lt;br /&gt;&lt;a href="http://fernando-castellanos.blogspot.com/2009/06/agile-coffeecamp-tijuana.html"&gt;blog de Fernando Castellanos&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-23643962624856136?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/23643962624856136/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=23643962624856136' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/23643962624856136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/23643962624856136'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/06/agile-programming-coffee-camp.html' title='Agile Programming Coffee Camp'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-8722874527535532080</id><published>2009-05-30T12:18:00.011-07:00</published><updated>2009-05-30T13:54:39.295-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='programacion'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>ASP.NET MVC Routing Validations</title><content type='html'>Ayer asistí a la reunión de la comunidad &lt;a href="http://tjnet.org/"&gt;TjNet &lt;/a&gt; fue la presentación sobre &lt;a href="http://asp.net/mvc"&gt;ASP.Net MVC&lt;/a&gt; que dieron &lt;a href="http://mario-chavez.blogspot.com/"&gt;Mario Chavez&lt;/a&gt; y &lt;a href="http://fernando-castellanos.blogspot.com/"&gt;Fernando Castellanos&lt;/a&gt;. Hubo pocos asistentes sin embargo hubo varias preguntas interesantes, incluso falto tiempo para seguir con las preguntas.&lt;br /&gt;&lt;br /&gt;Algo que se preguntó ahí en la reunión fue: ¿Como restringir el routing en ASP.NET MVC con expresiones regulares? Mencioné que si se podía pero en ese momento no me acorde como hacerlo ;), bueno pues aquí muestro un ejemplo.&lt;br /&gt;&lt;br /&gt;Una vez creado un nuevo proyecto de asp.net mvc desde visual studio, voy a agregar dos métodos al HomeController&lt;br /&gt;&lt;pre class="c-sharp" name="code"&gt;public ActionResult WelcomeByName(string name)&lt;br /&gt;{&lt;br /&gt;ViewData["Message"] = "Bienvenido, tu nombre es: " + name;&lt;br /&gt;return View("Index");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public ActionResult WelcomeById(int id)&lt;br /&gt;{&lt;br /&gt;ViewData["Message"] = "Welcome, your user ID is " + id;&lt;br /&gt;return View("Index");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;mi idea es que si el usuario pone la dirección &lt;span style="FONT-STYLE: italic"&gt;/Welcome/{cadena}&lt;/span&gt;&lt;br /&gt;se ejecutará el metodo WelcomeByName (mensaje en español) y si el usuario escribe /Welcome/{entero} se ejecutará el metodo WelcomeById (mensaje en ingles).&lt;br /&gt;&lt;br /&gt;Para ello debo de agregar entradas a mi tabla de rutas que se crea en el archivo Global.asax&lt;br /&gt;&lt;pre class="c-sharp" name="code"&gt;routes.MapRoute(&lt;br /&gt;"Welcome int",&lt;br /&gt;"Welcome/{id}",&lt;br /&gt;new { controller = "Home", action = "WelcomeById" },&lt;br /&gt;new { id = @"^\d+$" }&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;routes.MapRoute(&lt;br /&gt;"Welcome s",&lt;br /&gt;"Welcome/{name}",&lt;br /&gt;new { controller = "Home", action = "WelcomeByName", name = "anonimo" }&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;Estas dos entradas las puse antes de la entrada "Default". La primera ruta indica que espera una dirección con la forma "Welcome/{id}" para ejecutar la acción WelcomeById del HomeController, pero ademas agrega una restricción (usando expresiones regulares) que indica que solo se usara esta ruta si el parámetro "id" es entero positivo (o cero). Entonces si el valor de id no cumple con la condición no se usará esa ruta y se buscará otra para ser utilizada.&lt;br /&gt;&lt;br /&gt;La segunda ruta es similar a la primera solo que no tiene restricción alguna, por lo tanto si es entero el valor se ejecuta la primera, para las demás (que inicien con "Welcome") se ejecuta la segunda.&lt;br /&gt;&lt;br /&gt;Corro la aplicación y escribo la dirección en el navegador y compruebo que las rutas funcionen&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_GuIIcTHVIyM/SiGVAgnb7VI/AAAAAAAAAGo/G6aoQIC7SVI/s1600-h/routing1.JPG"&gt;&lt;img style="MARGIN: 0pt 10px 10px 0pt; WIDTH: 320px; FLOAT: left; HEIGHT: 194px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5341714469026000210" border="0" alt="" src="http://1.bp.blogspot.com/_GuIIcTHVIyM/SiGVAgnb7VI/AAAAAAAAAGo/G6aoQIC7SVI/s320/routing1.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_GuIIcTHVIyM/SiGVTw7y5YI/AAAAAAAAAGw/00m1kJM8uWI/s1600-h/routing2.JPG"&gt;&lt;img style="WIDTH: 320px; HEIGHT: 216px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5341714799823873410" border="0" alt="" src="http://1.bp.blogspot.com/_GuIIcTHVIyM/SiGVTw7y5YI/AAAAAAAAAGw/00m1kJM8uWI/s320/routing2.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pueden encontrar mas información sobre esto en la &lt;a href="http://altnet-hispano.pbworks.com/Reuni%C3%B3n+VAN+Hispano+2009-05-09"&gt;grabación &lt;/a&gt;de la VAN de &lt;a href="http://altnet-hispano.pbworks.com/"&gt;Alt.Net Hispano&lt;/a&gt;. Sobre ASP.NET MVC Avanzado explicada por &lt;a href="http://hadihariri.com/blogengine/"&gt;Hadi Hariri.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-8722874527535532080?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/8722874527535532080/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=8722874527535532080' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8722874527535532080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8722874527535532080'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/05/aspnet-mvc-routing-validations.html' title='ASP.NET MVC Routing Validations'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GuIIcTHVIyM/SiGVAgnb7VI/AAAAAAAAAGo/G6aoQIC7SVI/s72-c/routing1.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-8187848602804185583</id><published>2009-04-29T20:34:00.008-07:00</published><updated>2009-04-30T10:56:42.058-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Test'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='programacion'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Moq'/><title type='text'>ASP.NET MVC MyTwitter (Parte 2)</title><content type='html'>&lt;p&gt;Como parte de la serie sobre el desarrollo de una aplicación similar a Twitter para aprender ASP.NET MVC. Voy a seguir con la parte de registro (Signup). Esta semana he estado ocupado con trabajo, por eso agregaré poca funcionalidad en este post, la cual consiste en que una vez que el usuario se registre debemos de iniciar sesión con ese usuario, es decir identificarlo como un usuario Autentificado. &lt;/p&gt;  &lt;p&gt;Para ello es necesario escribir una clase (y una Interfaz) que me ayude en esta funcionalidad, para después hacer un mock de ella en el test del AccountController.&lt;/p&gt; &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;MyTwitter.Models&lt;br /&gt;{&lt;br /&gt;&lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IFormsAuthenticationTasks&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;  &lt;span style="color:blue;"&gt;void &lt;/span&gt;SetAuthCookie(&lt;span style="color:blue;"&gt;string &lt;/span&gt;username, &lt;span style="color:blue;"&gt;bool &lt;/span&gt;createPersistentCookie);&lt;br /&gt;  &lt;span style="color:blue;"&gt;void &lt;/span&gt;SignOut();&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Web.Security;&lt;br /&gt;&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;MyTwitter.Models&lt;br /&gt;{&lt;br /&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;FormsAuthenticationTasks &lt;/span&gt;&lt;br /&gt;   : MyTwitter.Models.&lt;span style="color: rgb(43, 145, 175);"&gt;IFormsAuthenticationTasks&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;  &lt;span style="color:blue;"&gt;public void &lt;/span&gt;SetAuthCookie(&lt;span style="color:blue;"&gt;string &lt;/span&gt;username, &lt;span style="color:blue;"&gt;&lt;br /&gt;      bool &lt;/span&gt;createPersistentCookie)&lt;br /&gt;  {&lt;br /&gt;      &lt;span style="color: rgb(43, 145, 175);"&gt;FormsAuthentication&lt;/span&gt;.SetAuthCookie(&lt;br /&gt;                   username, createPersistentCookie);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;public void &lt;/span&gt;SignOut()&lt;br /&gt;  {&lt;br /&gt;      &lt;span style="color: rgb(43, 145, 175);"&gt;FormsAuthentication&lt;/span&gt;.SignOut();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;agrego una variable de tipo IFormsAuthenticationTasks al AccountController y al constructor usado para las pruebas&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;AccountController &lt;/span&gt;: &lt;span style="color: rgb(43, 145, 175);"&gt;Controller&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;  &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IUserRepository &lt;/span&gt;userRepository;&lt;br /&gt;  &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IFormsAuthenticationTasks &lt;/span&gt;formsAuthenticationTasks;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;public &lt;/span&gt;AccountController(&lt;span style="color: rgb(43, 145, 175);"&gt;IUserRepository &lt;/span&gt;userRepository,&lt;br /&gt;        &lt;span style="color: rgb(43, 145, 175);"&gt;IFormsAuthenticationTasks &lt;/span&gt;formsAuthenticationTasks)&lt;br /&gt;  {&lt;br /&gt;      &lt;span style="color:blue;"&gt;this&lt;/span&gt;.userRepository = userRepository ?? &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;UserRepository&lt;/span&gt;();&lt;br /&gt;      &lt;span style="color:blue;"&gt;this&lt;/span&gt;.formsAuthenticationTasks =&lt;br /&gt;            formsAuthenticationTasks ?? &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;FormsAuthenticationTasks&lt;/span&gt;();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;public &lt;/span&gt;AccountController()&lt;br /&gt;      : &lt;span style="color:blue;"&gt;this&lt;/span&gt;(&lt;span style="color:blue;"&gt;null&lt;/span&gt;, &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;br /&gt;  {&lt;br /&gt;  }&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;escribo el test para la nueva funcionalidad&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;TestMethod&lt;/span&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;public void &lt;/span&gt;Login_User_After_Signup()&lt;br /&gt;{&lt;br /&gt;formsAuthenticationMock.Setup(&lt;br /&gt; fa =&amp;gt; fa.SetAuthCookie(&lt;span style="color: rgb(43, 145, 175);"&gt;It&lt;/span&gt;.IsAny&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;gt;(), &lt;span style="color: rgb(43, 145, 175);"&gt;It&lt;/span&gt;.IsAny&amp;lt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt;()));&lt;br /&gt;controller.Signup(&lt;span style="color:blue;"&gt;null&lt;/span&gt;);&lt;br /&gt;formsAuthenticationMock.VerifyAll();&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;implemento la funcionalidad en el método Signup del Account Controller para que la prueba pase, es solo agregar una línea antes del redirect&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;AcceptVerbs&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;HttpVerbs&lt;/span&gt;.Post)]&lt;br /&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;ActionResult &lt;/span&gt;Signup(&lt;span style="color: rgb(43, 145, 175);"&gt;FormCollection &lt;/span&gt;formValues)&lt;br /&gt;{&lt;br /&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;user = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;User&lt;/span&gt;();&lt;br /&gt;UpdateModel(user);&lt;br /&gt;userRepository.Add(user);&lt;br /&gt;userRepository.Save();&lt;br /&gt;&lt;br /&gt;formsAuthenticationTasks.SetAuthCookie(user.Username, &lt;span style="color:blue;"&gt;true&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;Redirect(&lt;span style="color: rgb(163, 21, 21);"&gt;"/invitations"&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;Hasta aquí con esta parte. Estuve tentado a llamarla “Parte 1.5” en lugar de “Parte 2”, por el poco contenido, pero se iba a empezar a complicar la numeración, continuaré con la serie en siguientes posts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-8187848602804185583?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/8187848602804185583/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=8187848602804185583' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8187848602804185583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8187848602804185583'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/04/aspnet-mvc-mytwitter-parte-3.html' title='ASP.NET MVC MyTwitter (Parte 2)'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-4154387723404623603</id><published>2009-04-24T11:31:00.001-07:00</published><updated>2009-04-24T11:58:06.089-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Test'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='programacion'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='base de datos'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Moq'/><title type='text'>ASP.NET MVC MyTwitter (Parte 1)</title><content type='html'>&lt;p&gt;En la &lt;a href="http://www.developeando.com/2009/04/mytwitter-aspnet-mvc-parte-0.html" target="_blank"&gt;parte 0&lt;/a&gt; de esta serie sobre ASP MVC MyTwitter hice la base de datos (la cual cambie un poco desde el pasado post) para iniciar el desarrollo de la aplicación. Ahora voy a generar el modelo de datos (LINQ to SQL classes) para eso en el folder de Models agrego el modelo de datos.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_GuIIcTHVIyM/SfIFVq0_8TI/AAAAAAAAAE4/PP6tkZEMB2c/s1600-h/image2.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh6.ggpht.com/_GuIIcTHVIyM/SfIFWaYq7yI/AAAAAAAAAE8/jCI581IP89M/image_thumb.png?imgmax=800" width="244" border="0" height="152" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Le doy clic con el botón derecho en el folder de Models y le hago clic en “Add/New Item” y selecciono “LINQ to SQL Classes” y le pongo el nombre MyTwitter.dbml&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_GuIIcTHVIyM/SfIFXNSZrBI/AAAAAAAAAFA/pQdkNEnxpK4/s1600-h/image9.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh5.ggpht.com/_GuIIcTHVIyM/SfIFXh3sJoI/AAAAAAAAAFE/zLNivarJWU0/image_thumb3.png?imgmax=800" width="244" border="0" height="139" /&gt;&lt;/a&gt; Arrastro desde el server explorer las tabla de la base de datos al modelo de datos, para que mi modelo quede así.&lt;/p&gt;  &lt;p&gt;Cambie el nombre de la tabla UserFriends por Friends y la columna Friend por FriendName. Esto fue con el propósito de que quedaran con mejor nombre las clases generadas por LinqToSql.  &lt;/p&gt;  &lt;p&gt;Ahora empiezo con la pagina de inicio, esta seria solo un formulario para iniciar sesión y un link para registrarse si es que no se tiene una cuenta. Para ello abro la página  Views/Home/Index.aspx y escribo el la forma en el HTML&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;form &lt;/span&gt;&lt;span style="color:red;"&gt;action&lt;/span&gt;&lt;span style="color:blue;"&gt;="/account/login" &lt;/span&gt;&lt;span style="color:red;"&gt;method&lt;/span&gt;&lt;span style="color:blue;"&gt;="post"&amp;gt;&lt;br /&gt;       &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;fieldset&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label &lt;/span&gt;&lt;span style="color:red;"&gt;for&lt;/span&gt;&lt;span style="color:blue;"&gt;="username"&amp;gt;&lt;/span&gt;Usuario&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.TextBox("username") &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.ValidationMessage("username", "*") &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;/span&gt;               &lt;br /&gt;           &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label &lt;/span&gt;&lt;span style="color:red;"&gt;for&lt;/span&gt;&lt;span style="color:blue;"&gt;="password"&amp;gt;&lt;/span&gt;Contrase&lt;span style="color:red;"&gt;&amp;amp;ntilde;&lt;/span&gt;a&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.Password("password") &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.ValidationMessage("password", "*") &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;input &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;="submit" &lt;/span&gt;&lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;="Ingresar" /&amp;gt;&lt;br /&gt;           &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Si no tienes una cuenta registrate &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;a &lt;/span&gt;&lt;span style="color:red;"&gt;href&lt;/span&gt;&lt;span style="color:blue;"&gt;="/signup"&amp;gt;&lt;/span&gt;aqui&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;a&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;       &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;fieldset&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;   &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;form&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;   &lt;/span&gt;&lt;/pre&gt;&lt;p&gt;De igual manera también modifico la prueba unitaria que viene por omisión en nuestro proyecto de test (MyTwitter.Tests) dentro del archivo HomeControllerTest.cs.&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;TestMethod&lt;/span&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;public void &lt;/span&gt;Index()&lt;br /&gt;{           &lt;br /&gt;  &lt;span style="color: rgb(43, 145, 175);"&gt;HomeController &lt;/span&gt;controller = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;HomeController&lt;/span&gt;();        &lt;br /&gt;  &lt;span style="color:blue;"&gt;var &lt;/span&gt;result = controller.Index();&lt;br /&gt;  &lt;span style="color: rgb(43, 145, 175);"&gt;Assert&lt;/span&gt;.IsNotNull(result);&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;Solo pruebo que el método Index() del HomeController regrese un View que no sea null. &lt;/p&gt;&lt;p&gt;Para realizar el registro de usuario voy a agregar un controller llamado AccountController, similar al que venia por default al crear al proyecto. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_GuIIcTHVIyM/SfIFYLAqrBI/AAAAAAAAAFI/Dvn1cuveBZk/s1600-h/image31.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh6.ggpht.com/_GuIIcTHVIyM/SfIFYvuJC9I/AAAAAAAAAFM/Bv0FmuOjM3I/image_thumb11.png?imgmax=800" width="244" border="0" height="100" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Hago clic en el folder Controllers y selecciono la opción “add controller”. y le pongo el nombre de “AccountController”.&lt;/p&gt;&lt;p&gt;Esto me agrega una nueva clase AccountController que hereda de la clase Controller con un método llamado Index. por el momento elimino el método Index, ya que todavía no lo voy a usar (casi no me gusta tener código que no hace nada) y agrego un método llamado Signup(). &lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; MyTwitter.Controllers&lt;br /&gt;{&lt;br /&gt;   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; AccountController : Controller&lt;br /&gt;   {&lt;br /&gt;       &lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult Signup()&lt;br /&gt;       {&lt;br /&gt;           &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; NotImplementedException();&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606&lt;/style&gt;Ahora el unit test&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_GuIIcTHVIyM/SfIFZDpxidI/AAAAAAAAAFQ/XA06nPvuwu4/s1600-h/image31%5B1%5D.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh4.ggpht.com/_GuIIcTHVIyM/SfIFZprbzOI/AAAAAAAAAFU/HgEs_KbxkIE/image_thumb1%5B1%5D.png?imgmax=800" width="244" border="0" height="81" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;En el folder Controllers del proyecto MyTwitter.Tests selecciono “Add &amp;gt; New Test..” y selecciono “Unit Test” y le doy el nombre de AccountControllerTest. Esto me agrega una clase con código de ejemplo. &lt;/p&gt;&lt;p&gt;Quito el código que genera para quedar con una prueba sencilla que verifica que se regrese un view para realizar el registro.&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;TestMethod&lt;/span&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;public void &lt;/span&gt;Return_A_View_For_Signup()&lt;br /&gt;{           &lt;br /&gt;   &lt;span style="color:blue;"&gt;var &lt;/span&gt;result = controller.Signup();&lt;br /&gt;   &lt;span style="color: rgb(43, 145, 175);"&gt;Assert&lt;/span&gt;.IsNotNull(result);&lt;br /&gt;}&lt;/pre&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #6060&lt;/style&gt;Implemento el método de Signup en el AccountController, este simplemente (como el test lo indica) regresará el view necesario para que el usuario ingrese sus datos de registro&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;ActionResult &lt;/span&gt;Signup()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:blue;"&gt;return &lt;/span&gt;View();&lt;br /&gt;}&lt;/pre&gt;Para agregar el View abro el menú contextual sobre el método Signup y selecciono “Add View”&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_GuIIcTHVIyM/SfIFaE3EirI/AAAAAAAAAFY/JVVtW6k15Lc/s1600-h/image6.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh5.ggpht.com/_GuIIcTHVIyM/SfIFa8Y3nZI/AAAAAAAAAFc/LUMSo8qII_c/image_thumb2.png?imgmax=800" width="244" border="0" height="50" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_GuIIcTHVIyM/SfIFbbPOomI/AAAAAAAAAFg/dZ4OOv-zlPM/s1600-h/image3.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh3.ggpht.com/_GuIIcTHVIyM/SfIFcZK7j1I/AAAAAAAAAFk/4cIeqvnhGJc/image_thumb1.png?imgmax=800" width="223" border="0" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Aparece un dialogo para agregar un view. aquí habilito la opción “Create a strongly-typed view” y selecciono (en “View data class:”) la clase MyTwitter.Models.User, En “View content” selecciono la opción Create. Esto para que VisualStudio escriba la mayoría del HTML por mi. Esto agrega un archivo (Views\Account\Signup.aspx) , lo abre en el editor y lo modifico para que quede en español.&lt;/p&gt;&lt;p&gt;El view queda así:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color:blue;"&gt;using &lt;/span&gt;(Html.BeginForm()) {&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;fieldset&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;legend&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Fields&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;legend&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label &lt;/span&gt;&lt;span style="color:red;"&gt;for&lt;/span&gt;&lt;span style="color:blue;"&gt;="Username"&amp;gt;&lt;/span&gt;Usuario:&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.TextBox(&lt;span style="color: rgb(163, 21, 21);"&gt;"Username"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.ValidationMessage(&lt;span style="color: rgb(163, 21, 21);"&gt;"Username"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"*"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label &lt;/span&gt;&lt;span style="color:red;"&gt;for&lt;/span&gt;&lt;span style="color:blue;"&gt;="FullName"&amp;gt;&lt;/span&gt;Nombre Completo:&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.TextBox(&lt;span style="color: rgb(163, 21, 21);"&gt;"FullName"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.ValidationMessage(&lt;span style="color: rgb(163, 21, 21);"&gt;"FullName"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"*"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label &lt;/span&gt;&lt;span style="color:red;"&gt;for&lt;/span&gt;&lt;span style="color:blue;"&gt;="Password"&amp;gt;&lt;/span&gt;Contraseña:&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.Password(&lt;span style="color: rgb(163, 21, 21);"&gt;"Password"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.ValidationMessage(&lt;span style="color: rgb(163, 21, 21);"&gt;"Password"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"*"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label &lt;/span&gt;&lt;span style="color:red;"&gt;for&lt;/span&gt;&lt;span style="color:blue;"&gt;="ConfirmPassword"&amp;gt;&lt;/span&gt;Confirmar Contraseña:&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.Password(&lt;span style="color: rgb(163, 21, 21);"&gt;"ConfirmPassword"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.ValidationMessage(&lt;span style="color: rgb(163, 21, 21);"&gt;"ConfirmPassword"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"*"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label &lt;/span&gt;&lt;span style="color:red;"&gt;for&lt;/span&gt;&lt;span style="color:blue;"&gt;="Email"&amp;gt;&lt;/span&gt;Correo Electronico:&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.TextBox(&lt;span style="color: rgb(163, 21, 21);"&gt;"Email"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.ValidationMessage(&lt;span style="color: rgb(163, 21, 21);"&gt;"Email"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"*"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label &lt;/span&gt;&lt;span style="color:red;"&gt;for&lt;/span&gt;&lt;span style="color:blue;"&gt;="Url"&amp;gt;&lt;/span&gt;Sitio Web:&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.TextBox(&lt;span style="color: rgb(163, 21, 21);"&gt;"Url"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.ValidationMessage(&lt;span style="color: rgb(163, 21, 21);"&gt;"Url"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"*"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label &lt;/span&gt;&lt;span style="color:red;"&gt;for&lt;/span&gt;&lt;span style="color:blue;"&gt;="Bio"&amp;gt;&lt;/span&gt;Biografia:&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.TextBox(&lt;span style="color: rgb(163, 21, 21);"&gt;"Bio"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.ValidationMessage(&lt;span style="color: rgb(163, 21, 21);"&gt;"Bio"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"*"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label &lt;/span&gt;&lt;span style="color:red;"&gt;for&lt;/span&gt;&lt;span style="color:blue;"&gt;="Location"&amp;gt;&lt;/span&gt;Ubicacion:&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;label&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.TextBox(&lt;span style="color: rgb(163, 21, 21);"&gt;"Location"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;                &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;= &lt;/span&gt;Html.ValidationMessage(&lt;span style="color: rgb(163, 21, 21);"&gt;"Location"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"*"&lt;/span&gt;) &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;           &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;               &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;input &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;="submit" &lt;/span&gt;&lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;="Create" /&amp;gt;&lt;br /&gt;           &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;       &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;fieldset&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;   &lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&amp;lt;%&lt;/span&gt; } &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;Las funciones de la clase Html me ayuda a no tener que escribir todo el HTML a pie (o mejor dicho a mano), no explicare como funcionan (creo que el nombre de cada método describe bien lo que hace) basta decir que escriben HTML. Uso Html.BeginForm sin parámetros en lugar de escribir el HTML para un &amp;lt;form&amp;gt; y así el action es al mismo url actual pero con el method=”post”. en este caso seria equivalente a escribir &amp;lt;form action=”/signup” method=”post”&amp;gt; y al cerrar el using (&amp;lt;% } %&amp;gt;) se escribe el &amp;lt;/form&amp;gt;.&lt;br /&gt;&lt;p&gt;Ahora voy a implementar el código que se ejecutará cuando el usuario haga submit a esta forma, para esto creo un nuevo método en el AccountController llamando también Signup la diferencia con el otro son los parámetros que recibe (en este caso los valores de la forma) y un atributo para que solo reciba peticiones de tipo POST.  &lt;/p&gt;&lt;pre class="csharpcode"&gt;[AcceptVerbs(HttpVerbs.Post)]&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult Signup(FormCollection formValues)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; NotImplementedException();&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;Antes de implementar la función quiero escribir un test para probar que el método Signup trate de guardar la información en la base de datos, pero sin hacer una llamada real a la base de datos, para esto voy a crear una clase UserReposotory que será la que se encargue de cargar los datos. También voy a crear una Interfaz para poder hacer un mock del repository. Esta clase e interfaz las pongo dentro del folder Models cada una en su propio archivo.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;MyTwitter.Models&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color:blue;"&gt;public interface &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IUserRepository&lt;br /&gt;   &lt;/span&gt;{&lt;br /&gt;       &lt;span style="color:blue;"&gt;void &lt;/span&gt;Add(&lt;span style="color: rgb(43, 145, 175);"&gt;User &lt;/span&gt;user);&lt;br /&gt;       &lt;span style="color: rgb(43, 145, 175);"&gt;User &lt;/span&gt;GetUser(&lt;span style="color:blue;"&gt;string &lt;/span&gt;username);&lt;br /&gt;       &lt;span style="color:blue;"&gt;void &lt;/span&gt;Save();&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;MyTwitter.Models&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;UserRepository &lt;/span&gt;: &lt;span style="color: rgb(43, 145, 175);"&gt;IUserRepository&lt;br /&gt;   &lt;/span&gt;{&lt;br /&gt;       &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;MyTwitterDataContext &lt;/span&gt;db;&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:blue;"&gt;public &lt;/span&gt;UserRepository()&lt;br /&gt;       {&lt;br /&gt;           db = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;MyTwitterDataContext&lt;/span&gt;();&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;User &lt;/span&gt;GetUser(&lt;span style="color:blue;"&gt;string &lt;/span&gt;username)&lt;br /&gt;       {&lt;br /&gt;           &lt;span style="color:blue;"&gt;return &lt;/span&gt;db.Users.FirstOrDefault(u =&amp;gt; u.Username == username);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Add(&lt;span style="color: rgb(43, 145, 175);"&gt;User &lt;/span&gt;user)&lt;br /&gt;       {&lt;br /&gt;           db.Users.InsertOnSubmit(user);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Save()&lt;br /&gt;       {&lt;br /&gt;           db.SubmitChanges();&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060;&lt;/style&gt;Ahora sí, ya puedo empezar a escribir mi prueba en AccountControllerTest. Para no tener que hacer uso de la base de datos en las pruebas unitarias utilizo &lt;a href="http://code.google.com/p/moq/" target="_blank"&gt;Moq&lt;/a&gt;, el cual es un mock framework que se puede descargar &lt;a href="http://code.google.com/p/moq/"&gt;aquí.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_GuIIcTHVIyM/SfIFc3xOsQI/AAAAAAAAAFo/EEl-6QkFWFM/s1600-h/image18.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh6.ggpht.com/_GuIIcTHVIyM/SfIFdUMaQRI/AAAAAAAAAFs/5uXaIyjhrC8/image_thumb6.png?imgmax=800" width="244" border="0" height="117" /&gt;&lt;/a&gt;  Una vez descargado moq, agrego una reference al moq.dll en el proyecto MyTwitter.Tests y agrego el using Moq; en el AccountControllerTest.cs. Con la ayuda de este framework vamos probar que el AccountController llame el metodo Add y Save del UserRepository.&lt;/p&gt;&lt;p&gt;Para no repetir la inicialización del repositoryMock y del controller, voy a agregarlos como variables de clase e inicializarlos en un método SetUp&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;TestClass&lt;/span&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;AccountControllerTest&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;   &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;AccountController &lt;/span&gt;controller;&lt;br /&gt;   &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;IUserRepository&lt;/span&gt;&amp;gt; repositoryMock;&lt;br /&gt;  &lt;br /&gt;   [&lt;span style="color: rgb(43, 145, 175);"&gt;TestInitialize&lt;/span&gt;]&lt;br /&gt;   &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Setup()&lt;br /&gt;   {&lt;br /&gt;       repositoryMock = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;IUserRepository&lt;/span&gt;&amp;gt;();&lt;br /&gt;       controller = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;AccountController&lt;/span&gt;(repositoryMock.Object);&lt;br /&gt;   }&lt;br /&gt;   ...&lt;/pre&gt;Ahora agrego los métodos de prueba&lt;br /&gt;&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;TestMethod&lt;/span&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;public void &lt;/span&gt;Add_And_Save_User_To_Repository()&lt;br /&gt;{           &lt;br /&gt;   repositoryMock.Setup(r =&amp;gt; r.Add(&lt;span style="color: rgb(43, 145, 175);"&gt;It&lt;/span&gt;.IsAny&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;User&lt;/span&gt;&amp;gt;()));&lt;br /&gt;   repositoryMock.Setup(r =&amp;gt; r.Save());        &lt;br /&gt;&lt;br /&gt;   controller.Signup(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;FormCollection&lt;/span&gt;());&lt;br /&gt;&lt;br /&gt;   repositoryMock.VerifyAll();&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;Además voy a agregar un test para probar que, una vez que se realice el registro del usuario, se envíe al usario a la pagina “/invitations” para que ahí el usuario pueda agregar amigos (friends) a quien seguir.&lt;/p&gt;&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;TestMethod&lt;/span&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;public void &lt;/span&gt;Redirect_To_Invitations_After_Signup()&lt;br /&gt;{                       &lt;br /&gt;   &lt;span style="color:blue;"&gt;var &lt;/span&gt;result = controller.Signup(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;FormCollection&lt;/span&gt;()) &lt;span style="color:blue;"&gt;as &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;RedirectResult&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(43, 145, 175);"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color: rgb(163, 21, 21);"&gt;"/invitations"&lt;/span&gt;, result.Url);&lt;br /&gt;}&lt;/pre&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060;&lt;/style&gt;Si corro el test ahora fallará porque no lo he implementado, entonces ahora lo que debo de hacer es que el test pase. Para ello declaro un IUserRepository en la clase AccountController y 2 constructores, uno que usare en el código en producción y el otro para las pruebas.&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;AccountController &lt;/span&gt;: &lt;span style="color: rgb(43, 145, 175);"&gt;Controller&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;   &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IUserRepository &lt;/span&gt;userRepository;&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:blue;"&gt;public &lt;/span&gt;AccountController(&lt;span style="color: rgb(43, 145, 175);"&gt;IUserRepository &lt;/span&gt;userRepository)&lt;br /&gt;   {&lt;br /&gt;       &lt;span style="color:blue;"&gt;this&lt;/span&gt;.userRepository = userRepository ?? &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;UserRepository&lt;/span&gt;();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:blue;"&gt;public &lt;/span&gt;AccountController()&lt;br /&gt;       : &lt;span style="color:blue;"&gt;this&lt;/span&gt;(&lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;br /&gt;   {&lt;br /&gt;   }&lt;br /&gt;   ...&lt;/pre&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060&lt;/style&gt;ahora si, por fin implemento el método Signup en el AccountController&lt;br /&gt;&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;AcceptVerbs&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;HttpVerbs&lt;/span&gt;.Post)]&lt;br /&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;ActionResult &lt;/span&gt;Signup(&lt;span style="color: rgb(43, 145, 175);"&gt;FormCollection &lt;/span&gt;formValues)&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color:blue;"&gt;var &lt;/span&gt;user = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;User&lt;/span&gt;();&lt;br /&gt;   UpdateModel(user);&lt;br /&gt;   userRepository.Add(user);&lt;br /&gt;   userRepository.Save();&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:blue;"&gt;return &lt;/span&gt;Redirect(&lt;span style="color: rgb(163, 21, 21);"&gt;"/invitations"&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;&lt;pre class="csharpcode"&gt;[tanto blog post para este método tan sencillo :) ]&lt;/pre&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_GuIIcTHVIyM/SfIFd-Dci_I/AAAAAAAAAFw/rdy2pDTzDbY/s1600-h/image21.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh4.ggpht.com/_GuIIcTHVIyM/SfIFedi8MAI/AAAAAAAAAF0/vHecQ2j-8EY/image_thumb7.png?imgmax=800" width="244" border="0" height="67" /&gt;&lt;/a&gt; Ejecuto las pruebas unitarias y verifico que el código hace lo que se supone debe hacer. &lt;/p&gt;&lt;p&gt;Si ejecuto la aplicación y en la pagina de inicio hago clic en el enlace para registrase me manda a “/signup” y me marca error por que no encuentra el recurso. Para que al buscar el recurso /signup se ejecute el action Signup del AccountController, debo de agregar un Route en el archivo Global.asax ( lo agrego antes del Route “Default”).&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;MvcApplication &lt;/span&gt;: System.Web.&lt;span style="color: rgb(43, 145, 175);"&gt;HttpApplication&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;   &lt;span style="color:blue;"&gt;public static void &lt;/span&gt;RegisterRoutes(&lt;span style="color: rgb(43, 145, 175);"&gt;RouteCollection &lt;/span&gt;routes)&lt;br /&gt;   {&lt;br /&gt;       routes.IgnoreRoute(&lt;span style="color: rgb(163, 21, 21);"&gt;"{resource}.axd/{*pathInfo}"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;       routes.MapRoute(&lt;br /&gt;           &lt;span style="color: rgb(163, 21, 21);"&gt;"Signup"&lt;/span&gt;,&lt;br /&gt;           &lt;span style="color: rgb(163, 21, 21);"&gt;"signup"&lt;/span&gt;,&lt;br /&gt;           &lt;span style="color:blue;"&gt;new &lt;/span&gt;{ controller = &lt;span style="color: rgb(163, 21, 21);"&gt;"Account"&lt;/span&gt;, action = &lt;span style="color: rgb(163, 21, 21);"&gt;"Signup" &lt;/span&gt;});&lt;br /&gt;&lt;br /&gt;       routes.MapRoute(&lt;br /&gt;           &lt;span style="color: rgb(163, 21, 21);"&gt;"Default"&lt;/span&gt;,                                              &lt;span style="color:green;"&gt;&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"{controller}/{action}/{id}"&lt;/span&gt;,                           &lt;span style="color:green;"&gt;&lt;br /&gt;           &lt;/span&gt;&lt;span style="color:blue;"&gt;new &lt;/span&gt;{ controller = &lt;span style="color: rgb(163, 21, 21);"&gt;"Home"&lt;/span&gt;, action = &lt;span style="color: rgb(163, 21, 21);"&gt;"Index"&lt;/span&gt;, id = &lt;span style="color: rgb(163, 21, 21);"&gt;"" &lt;/span&gt;}  &lt;span style="color:green;"&gt;&lt;br /&gt;       &lt;/span&gt;);           &lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:blue;"&gt;protected void &lt;/span&gt;Application_Start()&lt;br /&gt;   {&lt;br /&gt;       RegisterRoutes(&lt;span style="color: rgb(43, 145, 175);"&gt;RouteTable&lt;/span&gt;.Routes);&lt;br /&gt;   }&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060;&lt;/style&gt;con esto ya puedo hacer una pequeña prueba de integración.En la siguiente parte continuare con el desarrollo de esta aplicación.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-4154387723404623603?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/4154387723404623603/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=4154387723404623603' title='5 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4154387723404623603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/4154387723404623603'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/04/aspnet-mvc-mytwitter-parte-1.html' title='ASP.NET MVC MyTwitter (Parte 1)'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_GuIIcTHVIyM/SfIFWaYq7yI/AAAAAAAAAE8/jCI581IP89M/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-5551900631961033506</id><published>2009-04-22T15:27:00.001-07:00</published><updated>2009-04-22T15:35:05.927-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sql Server'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='programacion'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='base de datos'/><title type='text'>ASP.NET MVC MyTwitter (Parte 0)</title><content type='html'>&lt;p&gt;Para aprender acerca de ASP.NET MVC voy a realizar una aplicación de prueba que sería la versión en español de &lt;a href="http://twitter.com/"&gt;twitter&lt;/a&gt; (con esta aplicación solo pretendo aprender, no pretendo competir con &lt;a href="http://twitter.com/"&gt;twitter&lt;/a&gt;) que llamaré MyTwitter. Este post lo he titulado parte 0 de la serie por que solo escribiré el setup de la aplicación y a partir de la parte 1 empezare (ahora si) con el desarrollo.&lt;/p&gt;  &lt;p&gt;Antes de iniciar debo instalar el ASP MVC Framework, el cual se puede descargar &lt;a href="http://go.microsoft.com/fwlink/?LinkId=144444"&gt;aquí&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_GuIIcTHVIyM/Se-ZxQ-K5gI/AAAAAAAAAEI/cdfPn6iVoIo/s1600-h/image%5B14%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" align="left" src="http://lh5.ggpht.com/_GuIIcTHVIyM/Se-ZySJ8LRI/AAAAAAAAAEM/fYRSERfU_o8/image_thumb%5B10%5D.png?imgmax=800" width="244" height="132" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Una vez que instalé el MVC Framework puedo crear un nuevo proyecto en visual studio (no es un Web Site, sino un project).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://lh4.ggpht.com/_GuIIcTHVIyM/Se-Zz9JVGpI/AAAAAAAAAEQ/g0g4R9kWF6c/s1600-h/image%5B13%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_GuIIcTHVIyM/Se-Z0s8EIHI/AAAAAAAAAEU/CmUAZbVQeEU/image_thumb%5B9%5D.png?imgmax=800" width="244" height="170" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Después selecciono la plantilla de ASP.NET MVC Web Application y le doy el nombre de MyTwitter&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_GuIIcTHVIyM/Se-Z1jfVKhI/AAAAAAAAAEY/nfSNGBKMXos/s1600-h/image%5B17%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_GuIIcTHVIyM/Se-Z2Bb8zrI/AAAAAAAAAEc/ZIG63Z9EFgg/image_thumb%5B11%5D.png?imgmax=800" width="244" height="170" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Una vez hecho esto aparece una ventana que me pregunta si quiero un proyecto para las pruebas unitarias. Seleccione la opción de “Yes”. Esto creará una aplicación con 2 controllers (Home y Account). Adema incluye algunas pruebas unitarias para el proyecto de ejemplo. Para este ejemplo voy a quitar el AccountController (y su respectivo test) para crear uno propio. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_GuIIcTHVIyM/Se-Z3T_5A7I/AAAAAAAAAEg/Zb9yzW3iRyY/s1600-h/image%5B20%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_GuIIcTHVIyM/Se-Z4ZCzXRI/AAAAAAAAAEk/JoC3H6C0pGE/image_thumb%5B12%5D.png?imgmax=800" width="244" height="164" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Ahora voy a crear la base de datos. Haciendo clic con el botón derecho en el folder App_Data. Esa opción aparece si se le da con el botón derecho en cualquier parte del proyecto pero me gusta hacerlo sobre el App_Data folder por que así me aparecen los ítems filtrados.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_GuIIcTHVIyM/Se-Z5QblzOI/AAAAAAAAAEo/dUrvVV0PoYs/s1600-h/image%5B23%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_GuIIcTHVIyM/Se-Z6IUKDmI/AAAAAAAAAEs/zOH3NAUPHRI/image_thumb%5B13%5D.png?imgmax=800" width="244" height="153" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Selecciono SQL Server Database y le doy el nombre de MyTwitter.mdf. Una vez hecho esto me aparece la nueva base de datos bajo el folder de App_Data Dandole doble clic, me agrega una nueva conexión en el Server Explorer y la abre. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_GuIIcTHVIyM/Se-Z6XwgNnI/AAAAAAAAAEw/5JLdELSf0Oo/s1600-h/image%5B26%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_GuIIcTHVIyM/Se-Z7Gb749I/AAAAAAAAAE0/x9l3kXuPle4/image_thumb%5B14%5D.png?imgmax=800" width="133" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Ahora agrego algunas tablas para iniciar el desarrollo del sitio. Por lo pronto agregaremos&amp;#160; Users, Posts y UserFriends.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Con esto queda listo nuestro proyecto para empezar a agregarle funcionalidad. En el siguiente post (Parte 1) seguiré con el desarrollo de este proyecto de prueba “MyTwitter”.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-5551900631961033506?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/5551900631961033506/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=5551900631961033506' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5551900631961033506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5551900631961033506'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/04/mytwitter-aspnet-mvc-parte-0.html' title='ASP.NET MVC MyTwitter (Parte 0)'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_GuIIcTHVIyM/Se-ZySJ8LRI/AAAAAAAAAEM/fYRSERfU_o8/s72-c/image_thumb%5B10%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-1720994491179044948</id><published>2009-03-17T11:27:00.001-08:00</published><updated>2009-03-17T17:04:38.353-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programacion'/><category scheme='http://www.blogger.com/atom/ns#' term='Web 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Web 2.0 Coffee Camp TJ</title><content type='html'>&lt;p&gt;El Sábado 7 de marzo de 2009 nos reunimos en el Café D’Volada de Otay Constituyentes para discutir que es el Web 2.0. Fue una reunión que duro aproximadamente 2 horas. Lo que aprendí de la reunión es que para que una aplicación se pueda considerar como WEB 2.0 debe de cumplir con algunas (no todas) características:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Característica Social&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Los usuarios participan activamente en el contenido de la misma. El contenido son opiniones o expresiones personales y no simplemente datos, es decir el contenido es mas subjetivo que objetivo por lo tanto esta abierto a discusión y comentarios. En estos casos podemos encontrar sitios como &lt;a href="http://youtube.com"&gt;YouTube&lt;/a&gt;, &lt;a href="http://es.wikipedia.org"&gt;Wikipedia&lt;/a&gt; (contenido objetivo, pero abierto a discusión), &lt;a href="http://www.flickr.com/"&gt;flickr&lt;/a&gt;, &lt;a href="http://twitter.com"&gt;twitter&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Característica Tecnológica&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;El sitio utiliza Ajax, tiene un API para ser consumido por clientes desarrollados por terceros. Y pueden o no utilizar RIAS. Esta es una característica no obligatoria. En lo personal al inicio del termino Web 2.0 consideraba esta característica mas importante que la social (tal vez por que soy desarrollador).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Característica Visual&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Comentaron en la reunión (en lo personal no me ha tocado por que no soy diseñador) que algunas personas relacionan el termino web 2.0 con el aspecto visual de la aplicación. En lo general estuvimos de acuerdo en que esto no basta para que la aplicación sea considerada como WEB 2.0 (tómese en cuenta que a la reunión asistimos desarrolladores y diseñadores). Sin embargo eso me hizo pensar que si preguntamos en la calle a la mayoría de la gente tal vez para ellos web 2.0 requiere esta otra característica que para nosotros (desarrolladores y diseñadores) no es necesaria. Si para los que pagan los desarrollos y los diseños, el web 2.0 se refiere a lo visual y los efectos (muchas veces como resultado de la característica tecnológica) quizás esto deba ser considerado como una característica valida (aunque no me guste la idea). &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Solo discutieron aplicaciones publicas en el Internet, parece que una aplicación privada que corre dentro de una intranet no es considerada como Web 2.0 aunque la mayoría del contenido de estas aplicaciones es generados por los mismos usuarios de la empresa y pudiera utilizar Ajax. Tal vez si el contenido es social, es decir de opinión de los empleados y no datos generados por el negocio, si se considere Web 2.0 (Creo que es algo que debí preguntar)&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Algunas de las conclusiones personales de la reunión fueron que: siendo Web 2.0 un termino subjetivo, lo que para unos es web 2.0 para otros no lo es (generalmente depende de la perspectiva). Aunque creo que en lo que todos estuvimos de acuerdo es que: twitter si es Web 2.0. por su característica social.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Me quedó pendiente una pregunta...Si los comentarios de mi blog no son filtrados y cualquiera puede opinar ¿Los comentarios de mi blog son Web 2.0?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Puedes escuchar la reunión en:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dev3cast.com/"&gt;http://www.dev3cast.com/&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-1720994491179044948?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/1720994491179044948/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=1720994491179044948' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1720994491179044948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1720994491179044948'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/03/web-20-coffee-camp-tj.html' title='Web 2.0 Coffee Camp TJ'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-3213969453155893762</id><published>2009-03-04T15:24:00.000-08:00</published><updated>2009-03-04T16:01:26.412-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Podcast'/><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Podcasts</title><content type='html'>Esta una lista de los podcasts que actualmente escucho&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dotnetrocks.com/"&gt;.Net Rocks&lt;/a&gt;&lt;br /&gt; Ya un clasico de los podcasts, tiene la mejor calidad de audio y muy buenos invitados y temas sobre .Net&lt;br /&gt;&lt;br /&gt;&lt;a href="http://deepfriedbytes.com/"&gt;Deep Fried Bytes&lt;/a&gt;&lt;br /&gt; Hablan principalmente sobre desarrollo en .net&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.hanselminutes.com/"&gt;Hanselminutes&lt;/a&gt;&lt;br /&gt; Scott Hanselman web developer y ahora empleado de Microsoft trata varios temas&lt;br /&gt;&lt;br /&gt;&lt;a href="http://polymorphicpodcast.com/"&gt;Polymorphic Podcast&lt;/a&gt;&lt;br /&gt;Arquitectura y programación orientada a objetos en .Net (Ya tiene tiempo que no salen nuevos episodios)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.delphi.org/"&gt;The Poscast @ Delphi.org&lt;/a&gt;&lt;br /&gt; podcast sobre &lt;a href="http://www.codegear.com/products/delphi/"&gt;Delphi   &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.runasradio.com/"&gt;RunAs Radio&lt;/a&gt;&lt;br /&gt; Para profesionales de IT, no es desarrollo pero es bueno conocer sobre IT&lt;br /&gt;&lt;br /&gt;&lt;a href="http://startuppodcast.wordpress.com/"&gt;The Startup Success Podcast&lt;/a&gt;&lt;br /&gt; Podcast para Startups o MicroISVs varios consejos para iniciar tu propio negocio de software&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.stackoverflow.com/"&gt;stackoverflow&lt;/a&gt;&lt;br /&gt; Tratan temas sobre desarrollo y administración de equipos de desarrollo, principalmente hablan del sitio &lt;a href="http://stackoverflow.com/"&gt;stackoverflow.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://thirstydeveloper.com/"&gt;The Thirsty Developer&lt;/a&gt;&lt;br /&gt; Este de los mas recientes en mi lista, hablan principalmente de como se esta usando la tecnología.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dev3cast.com/"&gt;dev3cast&lt;/a&gt;&lt;br /&gt;Podcast de la &lt;a href="http://tjnet.org/"&gt;comunidad .Net en Tijuana&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.se-radio.net/"&gt;Software Engineering radio&lt;/a&gt;&lt;br /&gt;Ingeniería de software tratan temas que aplican a todas las plataforma y lenguages&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-3213969453155893762?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/3213969453155893762/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=3213969453155893762' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3213969453155893762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3213969453155893762'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/03/podcasts.html' title='Podcasts'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2427028089076759726</id><published>2009-02-25T09:58:00.000-08:00</published><updated>2009-02-25T10:08:09.801-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Basic'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='programacion'/><category scheme='http://www.blogger.com/atom/ns#' term='XML Literals'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Reunión 27 de la comunidad TJ.NET</title><content type='html'>Hoy será la &lt;a href="http://tjnet.org/Eventos/1717.aspx"&gt;reunión  27 de la comunidad&lt;/a&gt; &lt;a href="http://tjnet.org"&gt;TJ.NET&lt;/a&gt; donde estaré presentando el tema de XML Literals en Visual Basic.&lt;br /&gt;&lt;br /&gt;Mostrare como carga un archivo XML y con los datos crear un objeto del dominio y a partir de un objeto del dominio del problema crear un archivo XML. Ademas de mostrar como realizar una búsqueda en el documento XML utilizando LinqToXml.&lt;br /&gt;&lt;br /&gt;Debido al poco tiempo sera una presentacion sencilla sin entrar mucho a detalle. Espero que los asistentes tengan preguntas, para hacerlo mas interesante.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2427028089076759726?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2427028089076759726/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2427028089076759726' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2427028089076759726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2427028089076759726'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/02/reunion-27-de-la-comunidad-tjnet.html' title='Reunión 27 de la comunidad TJ.NET'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-8139887632329495407</id><published>2009-02-01T13:35:00.001-08:00</published><updated>2009-02-03T17:38:29.665-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NMock'/><category scheme='http://www.blogger.com/atom/ns#' term='Unit Test'/><category scheme='http://www.blogger.com/atom/ns#' term='NUnit'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>Iniciando con Test Driven Development (TDD)</title><content type='html'>Al iniciar con &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD &lt;/a&gt;, en algunos proyectos, note que esto ha hecho que cambie mi manera de programar. Ya que al tratar de escribir código de manera que sea testeable, termino escribiendo código mas desacoplado y con mas clases que hacen un trabajo mas especifico y con un poco de &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;dependency injection&lt;/a&gt;. también he notado que ahora escribo mucho mas código y el resultado a veces es el mismo que antes (con la desventaja que me tarde mas). Aunque muchas veces los tests me han ayudado a encontrar errores mas rápido y me siento mas seguro de que el código que escribo funciona correctamente.&lt;br /&gt;&lt;br /&gt;Por el momento estoy utilizando &lt;a href="http://www.nunit.org/"&gt;NUnit &lt;/a&gt;y &lt;a href="http://www.nmock.org/"&gt;NMock&lt;/a&gt; para mis unit test en .Net. Para mi gusto estos frameworks están bien para el tipo de tests que realizo.&lt;br /&gt;&lt;br /&gt;Por ejemplo, supongamos que estamos construyendo un registro para usuarios. Y queremos que (cuando un usuario nuevo se registre) se validen los datos del usuario, se inserte a la base de datos y se envié correo de bienvenida.&lt;br /&gt;&lt;br /&gt;Al escribir el test para el método de registro, debemos de evitar que este tengan dependencias en otras partes del sistema ya que solo queremos validar que se realicen las reglas de negocio y no tanto como se implementa cada tarea (para cada tarea se realizarán sus propias pruebas unitarias) esto me hace escribir mas clases de tal forma que pueda hacer &lt;a href="http://en.wikipedia.org/wiki/Mock_object"&gt;mock objects&lt;/a&gt; para las dependencias.&lt;br /&gt;&lt;br /&gt;Entonces en lugar de una sola clase para el registro (&lt;span style="font-style: italic;"&gt;RegistrationService&lt;/span&gt;) que se encargue de validar, insertar y enviar correo, tendremos varias clases que colaboran para realizar el registro. Como pueden ser: &lt;span style="font-style: italic;"&gt;RegistrationService&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;RegistrationValidator&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;EmailService &lt;/span&gt;y &lt;span style="font-style: italic;"&gt;RegistrationDAL&lt;/span&gt;. Así podemos probar que el &lt;span style="font-style: italic;"&gt;RegistrationService &lt;/span&gt;realice la regla de negocio y por separado probar cada una de las tareas. Ademas, si por alguna razón cambia la manera de validar el registro, solo tendríamos que modificar la clase &lt;span style="font-style: italic;"&gt;RegistrationValidator &lt;/span&gt;y no tenemos que cambiar el resto del proceso de registro. Como ven esto implica realizar mas código, pero se supone que a la larga es mejor, Ahora tenemos código que valida nuestro código.&lt;br /&gt;&lt;br /&gt;En mi caso realizar &lt;a href="http://en.wikipedia.org/wiki/Unit_testing"&gt;unit tests&lt;/a&gt; si me ha ayudado a encontrar errores y a estar seguro de que el código hace lo que tiene que hacer. Aunque debo admitir que hay veces que quisiera no tener que escribir tantas clases y pruebas para cada una de estas clases. En fin todo es cosa de saber que no todo requiere &lt;a href="http://en.wikipedia.org/wiki/Unit_testing"&gt;unit test&lt;/a&gt; y encontrar el balance entre lo que lo requiere y lo que no.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-8139887632329495407?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/8139887632329495407/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=8139887632329495407' title='4 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8139887632329495407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8139887632329495407'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/02/iniciando-con-test-driven-development_01.html' title='Iniciando con Test Driven Development (TDD)'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-6315896562386231366</id><published>2009-02-01T10:25:00.001-08:00</published><updated>2010-04-21T13:37:34.713-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Firebird'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><title type='text'>Firebird 2.1 List Function</title><content type='html'>The List function in &lt;a href="http://www.firebirdsql.org/"&gt;Firebird&lt;/a&gt; 2.1.&lt;br /&gt;&lt;br /&gt;This is an aggregate function that returns a string with the field values concatenated using a delimiter. the default delimiter is the comma. So it's similar to the SUM function, but instead of adding numbers, this function concatenate strings. if some of the values is null then the function returns null.&lt;br /&gt;&lt;br /&gt;So suppose I have 2 tables, projects and resources, and I know that a project will have a few resources assigned. Now I need to write a report of projects showing their resources assigned.&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;CREATE TABLE projects(&lt;br /&gt;   project_id INTEGER,&lt;br /&gt;   name string   &lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;CREATE TABLE resources(&lt;br /&gt;   project_id integer,&lt;br /&gt;   user_name string&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Without the LIST function I have to write this query&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;SELECT&lt;br /&gt;  p.project_id as id,&lt;br /&gt;  p.name,&lt;br /&gt;  r.user_name&lt;br /&gt;FROM&lt;br /&gt;  projects p INNER JOIN&lt;br /&gt;  resources r ON p.project_id = r.project_id&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;my result will be like this&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;id  name       user_name&lt;br /&gt;-------------------------&lt;br /&gt;1   Project_1  Steve&lt;br /&gt;1   Project_1  John&lt;br /&gt;2   Project_2  Jim&lt;br /&gt;2   Project_2  Ed&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then in the report I will need to group the records with the same project_id so I don't show duplicate projects for each resource assigned.&lt;br /&gt;&lt;br /&gt;Now with &lt;a href="http://www.firebirdsql.org/"&gt;Firebird &lt;/a&gt;2.1 I can write the query using the LIST function&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;SELECT&lt;br /&gt;  p.project_id AS id,&lt;br /&gt;  p.name,&lt;br /&gt;  LIST(r.user_name, ', ') AS resources&lt;br /&gt;FROM&lt;br /&gt;  projects p INNER JOIN&lt;br /&gt;  resources r ON p.project_id = r.project_id&lt;br /&gt;GROUP BY&lt;br /&gt;  p.project_id,&lt;br /&gt;  p.name&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;my result will be like this&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;id  name       resources&lt;br /&gt;-----------------------------&lt;br /&gt;1   Project_1  Steve, John&lt;br /&gt;2   Project_2  Jim, Ed&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;then in my report I only need to show the results of my query, I don't need to create groups.&lt;br /&gt;&lt;br /&gt;The list function returns a BLOB data type, so if I need to display the result in a grid I often CAST the result to varchar. The delimiter parameter is not required (I added because I like to add a space after the comma). You can see more details of how to use the LIST function in the &lt;a href="http://www.firebirdsql.org/rlsnotes/Firebird-2.1-ReleaseNotes.pdf"&gt;Firebird 2.1 Release Notes&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This function is also useful in reports when you need details values in the same row as the master data like in reports headers or footers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-6315896562386231366?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/6315896562386231366/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=6315896562386231366' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6315896562386231366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6315896562386231366'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2009/02/firebird-21-list-function.html' title='Firebird 2.1 List Function'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-1720631552105843519</id><published>2008-12-07T13:59:00.000-08:00</published><updated>2008-12-07T15:19:25.232-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Firebird'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><title type='text'>Firebird 2.1 UPDATE OR INSERT</title><content type='html'>Another great feature that I like in &lt;a href="http://firebirdsql.org/"&gt;Firebird &lt;/a&gt;2.1 is the UPDATE OR INSERT statement. It's a really time saver and it makes the SQL cleaner.&lt;br /&gt;&lt;br /&gt;For example suppose I have a products table like the one I use in my last &lt;a href="http://mariohcornejo.blogspot.com/2008/09/firebird-21-domains-in-psql.html"&gt;post &lt;/a&gt;and an inventory table to store the product stock. Before Firebird 2.1 if I want to set the stock for a product I needed to check if a record for that product_id already exists; if the product_id already exists then I write an update. If not then I write an insert statement. So I ended up with something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;IF EXISTS(SELECT * FROM inventory WHERE product_id = :product_id ) THEN&lt;br /&gt;  UPDATE&lt;br /&gt;    inventory&lt;br /&gt;  SET&lt;br /&gt;    stock = :stock&lt;br /&gt;  WHERE&lt;br /&gt;    product_id = :product_id;&lt;br /&gt;ELSE&lt;br /&gt;  INSERT INTO inventory&lt;br /&gt;    (product_id, stock)&lt;br /&gt;  VALUES&lt;br /&gt;    (:product_id, :stock);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this example I only update one field but when I have to update a big table I ended up with a big chunk of code and thinking: "there should be another (better) way to do this".&lt;br /&gt;&lt;br /&gt;Fortunately now with Firebird 2.1 there is a better way to do it, I only need to use the UPDATE OR INSERT statement and the engine will take care of checking if the record already exists, based on the primary key value. If the table does not have a primary key defined then I should use the MATCHING keyword with the columns I want to match. So in this example the sql can look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="sql"&gt;--product_id is the primary key&lt;br /&gt;&lt;br /&gt;UPDATE OR INSERT INTO inventory&lt;br /&gt;  (product_id, stock)&lt;br /&gt;VALUES&lt;br /&gt;  (:product_id, :stock);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;or like this&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="sql"&gt;--product_id is not defined as the primary key&lt;br /&gt;&lt;br /&gt;UPDATE OR INSERT INTO inventory&lt;br /&gt;  (product_id, stock)&lt;br /&gt;VALUES&lt;br /&gt;  (:product_id, :stock)&lt;br /&gt;MATCHING &lt;br /&gt;  (product_id);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This code looks much cleaner and does not need any comments to explain what is going on.&lt;br /&gt;&lt;br /&gt;I really like this new feature.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-1720631552105843519?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/1720631552105843519/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=1720631552105843519' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1720631552105843519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1720631552105843519'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2008/12/firebird-21-update-or-insert.html' title='Firebird 2.1 UPDATE OR INSERT'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2896672871917746670</id><published>2008-09-02T21:34:00.000-07:00</published><updated>2008-09-08T10:38:07.021-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Firebird'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><title type='text'>Firebird 2.1 Domains in PSQL</title><content type='html'>I Often use this domains in my &lt;a href="http://firebirdsql.org/"&gt;Firebird &lt;/a&gt;databases&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;CREATE DOMAIN STRING AS VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ES_ES_CI_AI; /* for Spanish text */&lt;br /&gt;CREATE DOMAIN MONEY AS DECIMAL(15, 2);&lt;br /&gt;CREATE DOMAIN BOOL AS SMALLINT CHECK VALUE = 0 OR VALUE = 1;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So I can use them in my tables definitions like this:&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;CREATE TABLE PRODUCTS(&lt;br /&gt;    ID INTEGER,&lt;br /&gt;    DESCRIPTION STRING,&lt;br /&gt;    PRICE MONEY,&lt;br /&gt;    ACTIVE BOOL&lt;br /&gt;)&lt;br /&gt;ALTER TABLE PRODUCTS ADD CONSTRAINT PK_PRODUCTOS PRIMARY KEY (ID);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Before Firebird 2.1 when I wanted to create a stored procedure I had to write the data type of the domain instead of the domain name, like in the table definition, so I had to check the domain definition and write the data type on the procedure definition, although &lt;a href="http://ibexpert.net/ibe/"&gt;IBExpert &lt;/a&gt;help with that, my Stored Proc definition end it up not using the domains like this:&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;CREATE PROCEDURE INSERT_PRODUCT(&lt;br /&gt;    DESCRIPTION VARCHAR(50),&lt;br /&gt;    PRICE DECIMAL(15, 2),&lt;br /&gt;    ACTIVE SMALLINT&lt;br /&gt;)&lt;br /&gt;BEGIN&lt;br /&gt;  ...&lt;br /&gt;END&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now with version 2.1 I can use domain in PSQL. I just need to type the domain name if i want to inheriting the check clause and the default value, or I can use the &lt;span style="color: rgb(51, 102, 255);"&gt;TYPE OF&lt;/span&gt; keyword if I just want the data type so I can define something like this:&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;CREATE PROCEDURE INSERT_PRODUCT(&lt;br /&gt;    DESCRIPTION STRING,&lt;br /&gt;    PRICE TYPE OF MONEY,&lt;br /&gt;    ACTIVE BOOL&lt;br /&gt;)&lt;br /&gt;BEGIN&lt;br /&gt;  ...&lt;br /&gt;END&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This way it seems that there is more consistency on my data types.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2896672871917746670?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2896672871917746670/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2896672871917746670' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2896672871917746670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2896672871917746670'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2008/09/firebird-21-domains-in-psql.html' title='Firebird 2.1 Domains in PSQL'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-8742107651109859720</id><published>2008-08-28T18:34:00.000-07:00</published><updated>2008-08-28T18:47:30.173-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Firebird'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Authentication'/><category scheme='http://www.blogger.com/atom/ns#' term='base de datos'/><title type='text'>Firebird 2.1 Autentificar con Windows</title><content type='html'>La mayoría de las aplicaciones que desarrollo que utilizan &lt;a href="http://firebirdsql.org"&gt;Firebird &lt;/a&gt;son de tipo Cliente/Servidor lo cual hace que el deba de guardar al usuario y contraseña en la cadena de conexión almacenada en la maquina cliente.&lt;br /&gt;&lt;br /&gt;Ahora con Firebird 2.1 puedo usar los usuarios de windows como usuarios de la base de datos, de este modo no necesito almacenar el usuario y contraseña en la maquina cliente.&lt;br /&gt;&lt;br /&gt;Utilizando &lt;a href="http://www.codegear.com/products/delphi/win32"&gt;Delphi&lt;/a&gt; o &lt;a href="http://www.codegear.com/products/cppbuilder"&gt;C++ Builder&lt;/a&gt; con &lt;a href="http://en.wikipedia.org/wiki/DbExpress"&gt;DbExpress&lt;/a&gt; para conectarme a la base de datos puedo agregar el archivo dbConnections.ini y dejar en blanco los valores de user_name y password. El archivo quedaría similar a esto:&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;[MyFirebirdDatabase]&lt;br /&gt;DriverName=INTERBASE&lt;br /&gt;GETDRIVERFUNC=getSQLDriverINTERBASE&lt;br /&gt;DATABASE=Server:Database&lt;br /&gt;PASSWORD=&lt;br /&gt;USER_NAME=&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;SQLDIALECT=3&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Si uso .Net y el &lt;a href="http://www.firebirdsql.org/dotnetfirebird/"&gt;Firebird .Net Data Provider&lt;/a&gt; la cadena de conexión puede quedar algo asi:&lt;br /&gt;&lt;span class="csKeyword"  style="font-size:78%;"&gt;Database&lt;/span&gt;&lt;span style="font-size:78%;"&gt;=&lt;/span&gt;&lt;span class="csValue"  style="font-size:78%;"&gt;MyDatabase.fdb&lt;/span&gt;&lt;span style="font-size:78%;"&gt;;&lt;/span&gt;&lt;span class="csKeyword"  style="font-size:78%;"&gt;DataSource&lt;/span&gt;&lt;span style="font-size:78%;"&gt;=&lt;/span&gt;&lt;span class="csValue"  style="font-size:78%;"&gt;MyServer&lt;/span&gt;&lt;span style="font-size:78%;"&gt;;&lt;/span&gt;&lt;span class="csKeyword"  style="font-size:78%;"&gt;Dialect&lt;/span&gt;&lt;span style="font-size:78%;"&gt;=&lt;/span&gt;&lt;span class="csValue"  style="font-size:78%;"&gt;3&lt;/span&gt;&lt;span style="font-size:78%;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Si el usuario es administrador entonces ingresará al servidor de firebird como el usuario SYSADMIN si no usara el usuario d windows actual.&lt;br /&gt;&lt;br /&gt;Ahora solo debo de agregar los usuarios de windows a los usuarios de la base de datos y windows se encargará de autentificar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-8742107651109859720?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/8742107651109859720/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=8742107651109859720' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8742107651109859720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/8742107651109859720'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2008/08/firebird-21-autentificar-con-windows.html' title='Firebird 2.1 Autentificar con Windows'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-6965004198488494800</id><published>2008-08-28T17:55:00.000-07:00</published><updated>2008-08-28T18:41:44.130-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Firebird'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Authentication'/><title type='text'>Firebird Windows Authentication</title><content type='html'>Most of the applications I write that use &lt;a href="http://firebirdsql.org/"&gt;Firebird &lt;/a&gt;are Client/Server applications storing the user name and password to access the database in the connection string in the client machine.&lt;br /&gt;&lt;br /&gt;Now with Firebird 2.1 you can use windows authentication so the client will use the windows user to log on to the server. This way I don't need to store the user name and password on the connection string in the client.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/sqlserver/2008/en/us/default.aspx"&gt;MS SQL Server&lt;/a&gt; has this &lt;a href="http://msdn.microsoft.com/en-us/library/aa905171%28SQL.80%29.aspx"&gt;feature&lt;/a&gt; for long time now. but it's great to have it on Firebird too.&lt;br /&gt;&lt;br /&gt;Using &lt;a href="http://www.codegear.com/products/delphi/win32"&gt;Delphi&lt;/a&gt; or &lt;a href="http://www.codegear.com/products/cppbuilder"&gt;C++ Builder&lt;/a&gt; with &lt;a href="http://en.wikipedia.org/wiki/DbExpress"&gt;DbExpress&lt;/a&gt; to accesss firebird in the dbconnections.ini file I just leave blank the user_name and password values, so I could have something like this:&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;[MyFirebirdDatabase]&lt;br /&gt;DriverName=INTERBASE&lt;br /&gt;GETDRIVERFUNC=getSQLDriverINTERBASE&lt;br /&gt;DATABASE=Server:Database&lt;br /&gt;PASSWORD=&lt;br /&gt;USER_NAME=&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;SQLDIALECT=3&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Using the &lt;a href="http://www.firebirdsql.org/dotnetfirebird/"&gt;Firebird .Net Data Provider&lt;/a&gt; the connection string will end up like this:&lt;br /&gt;&lt;span class="csKeyword"  style="font-size:78%;"&gt;Database&lt;/span&gt;&lt;span style="font-size:78%;"&gt;=&lt;/span&gt;&lt;span class="csValue"  style="font-size:78%;"&gt;MyDatabase.fdb&lt;/span&gt;&lt;span style="font-size:78%;"&gt;;&lt;/span&gt;&lt;span class="csKeyword"  style="font-size:78%;"&gt;DataSource&lt;/span&gt;&lt;span style="font-size:78%;"&gt;=&lt;/span&gt;&lt;span class="csValue"  style="font-size:78%;"&gt;MyServer&lt;/span&gt;&lt;span style="font-size:78%;"&gt;;&lt;/span&gt;&lt;span class="csKeyword"  style="font-size:78%;"&gt;Dialect&lt;/span&gt;&lt;span style="font-size:78%;"&gt;=&lt;/span&gt;&lt;span class="csValue"  style="font-size:78%;"&gt;3&lt;/span&gt;&lt;span style="font-size:78%;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If the windows user is an administrator it will log in to the server as the SYSADMIN user. if the user is not an admin then the user will log in as the windows user.&lt;br /&gt;&lt;br /&gt;Now I only have to add the windows users as database users and Windows will take care of authenticate them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-6965004198488494800?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/6965004198488494800/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=6965004198488494800' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6965004198488494800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/6965004198488494800'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2008/08/firebird-windows-authentication.html' title='Firebird Windows Authentication'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-3598818769092332297</id><published>2008-07-02T17:42:00.000-07:00</published><updated>2008-07-02T18:12:42.034-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Firebird'/><category scheme='http://www.blogger.com/atom/ns#' term='base de datos'/><title type='text'>Firebird 2.1</title><content type='html'>Estoy empezando a usar &lt;a href="http://firebirdsql.org/"&gt;Firebird &lt;/a&gt;2.1 y estoy contento con las nuevas características. Aun no he tenido de oportunidad de usar todo lo nuevo, aquí esta una lista de lo nuevo que he estado usando, espero escribir de cada una de ella con mas detalle en los próximos posts&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Seguridad usando usuarios de Windows&lt;/li&gt;&lt;li&gt;Parámetros Opcionales en procedimientos almacenados&lt;/li&gt;&lt;li&gt;Dominios en los parámetros de los procedimientos&lt;/li&gt;&lt;li&gt;Natural Join&lt;/li&gt;&lt;li&gt;La función List&lt;/li&gt;&lt;li&gt;Sentencia Update or Insert&lt;/li&gt;&lt;/ul&gt;Hay mas características en la nueva versión, que aun no he tenido oportunidad de utilizar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-3598818769092332297?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/3598818769092332297/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=3598818769092332297' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3598818769092332297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3598818769092332297'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2008/07/firebird-21.html' title='Firebird 2.1'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2739487404136553624</id><published>2008-05-19T21:20:00.000-07:00</published><updated>2008-05-19T21:37:13.364-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenXML'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenOffice.org'/><category scheme='http://www.blogger.com/atom/ns#' term='Office 2007'/><title type='text'>Abrir Documentos de MS Office 2007 con OpenOffice.org 2.4</title><content type='html'>Para abrir documentos con el formato de open Xml (.docx, xlsx, pptx) con &lt;a href="http://openoffice.org"&gt;openOffice.org&lt;/a&gt; estoy utilizando un convertidor &lt;a href="http://katana.oooninja.com/w/odf-converter-integrator"&gt;http://katana.oooninja.com/w/odf-converter-integrator&lt;/a&gt;, este programa crea una copia del archivo a un formato que OpenOffice.org puede abrir. Hasta ahora todos los archivos que he probado han sido convertidos con calidad.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2739487404136553624?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2739487404136553624/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2739487404136553624' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2739487404136553624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2739487404136553624'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2008/05/abrir-documentos-de-ms-office-2007-con.html' title='Abrir Documentos de MS Office 2007 con OpenOffice.org 2.4'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-2979914385151353980</id><published>2008-03-02T22:48:00.000-08:00</published><updated>2008-03-02T23:10:26.217-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeGear'/><category scheme='http://www.blogger.com/atom/ns#' term='Firebird'/><category scheme='http://www.blogger.com/atom/ns#' term='DBX4'/><category scheme='http://www.blogger.com/atom/ns#' term='C++ Builder'/><title type='text'>Firebird and DBX4</title><content type='html'>&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style=";font-family:verdana;font-size:100%;"  lang="EN-US" &gt;Although &lt;a href="http://www.firebirdsql.org/"&gt;Firebird &lt;/a&gt;is not officially supported by the &lt;a href="http://www.codegear.com/products/interbase"&gt;Interbase &lt;/a&gt;dbexpress driver it can be used without problems until the &lt;a href="http://www.codegear.com/products/bds2006"&gt;BSD 2006&lt;/a&gt; (and the &lt;a href="http://www.turboexplorer.com/"&gt;Turbo &lt;/a&gt;versions).&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style=";font-family:verdana;font-size:100%;"  lang="EN-US" &gt;Now with &lt;a href="http://www.codegear.com/products/delphi/win32"&gt;Delphi 2007&lt;/a&gt;, &lt;a href="http://www.codegear.com/products/radstudio"&gt;RAD Studio&lt;/a&gt; and DBX4, firebird can still be use with &lt;/span&gt;&lt;span style=";font-family:verdana;font-size:100%;"  lang="EN-US" &gt;Interbase &lt;/span&gt;&lt;span style=";font-family:verdana;font-size:100%;"  lang="EN-US" &gt;driver, except if is used on Blobs fields; they allow reading but does not allow updating. This presents a problem when migrate applications to the latest version of Delphi and RAD Studio. This was &lt;a href="http://qc.codegear.com/wc/qcmain.aspx?d=42845"&gt;reported &lt;/a&gt;in &lt;a href="http://qc.codegear.com/"&gt;Quality Central&lt;/a&gt; but &lt;a href="http://www.codegear.com/"&gt;CodeGear&lt;/a&gt; closed the post &lt;a href="http://qc.codegear.com/wc/qcmain.aspx?rc=42845"&gt;arguing &lt;/a&gt;that Firebird is not Interbase, and the driver was written for Interbase, therefore it’s not a bug.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"&gt;&lt;span style=";font-family:verdana;font-size:100%;"  lang="EN-US" &gt;I suppose Firebird and Interbase will be separating each other more on future versions. I hope CodeGear will develop a driver for firebird because there are many applications made with Delphi and C++ Builder that are using Firebird.&lt;/span&gt;&lt;span style="" lang="EN-US"&gt; &lt;/span&gt;&lt;span style="" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-2979914385151353980?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/2979914385151353980/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=2979914385151353980' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2979914385151353980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/2979914385151353980'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2008/03/firebird-dbx4.html' title='Firebird and DBX4'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-3717284233572630955</id><published>2008-03-02T21:53:00.000-08:00</published><updated>2008-03-02T22:19:53.618-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Firebird'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='C++ Builder'/><category scheme='http://www.blogger.com/atom/ns#' term='base de datos'/><title type='text'>Firebird DBX4 Blob Fields</title><content type='html'>&lt;p style="font-family: verdana;" class="MsoNormal"&gt;Aunque &lt;a href="http://www.firebirdsql.org/"&gt;Firebird &lt;/a&gt;no es oficialmente soportado por el driver de interbase para dbexpress, se puede utilizar sin problemas hasta la versión de &lt;a href="http://www.codegear.com/products/bds2006"&gt;BSD 2006&lt;/a&gt; (incluyendo los &lt;a href="http://www.turboexplorer.com/"&gt;Turbo&lt;/a&gt;).&lt;br /&gt;Ahora con la versión 2007 y DBX4 se puede seguir utilizando el driver de &lt;a href="http://www.codegear.com/products/Interbase"&gt;interbase&lt;/a&gt;, excepto si se usa campos Blobs. Ya que estos solo pueden ser leídos, pero no pueden ser actualizados. Lo cual representa un problema al querer migrar aplicaciones a la nueva versión de delphi y/o &lt;a href="http://www.codegear.com/products/radstudio"&gt;RAD Studio&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p style="font-family: verdana;" class="MsoNormal"&gt;"El Problema" fue &lt;a href="http://qc.codegear.com/wc/qcmain.aspx?d=42845"&gt;reportado &lt;/a&gt;en &lt;a href="http://qc.codegear.com/"&gt;Quality Central&lt;/a&gt; pero &lt;a href="http://www.codegear.com/"&gt;CodeGear &lt;/a&gt;cerró el post &lt;a href="http://qc.codegear.com/wc/qcmain.aspx?rc=42845"&gt;argumentando &lt;/a&gt;que &lt;a href="http://www.firebirdsql.org/"&gt;Firebird &lt;/a&gt;no es &lt;a href="http://www.codegear.com/products/Interbase"&gt;Interbase &lt;/a&gt;y el driver fue escritó para &lt;a href="http://www.codegear.com/products/Interbase"&gt;Interbase&lt;/a&gt;, por lo tanto no es un bug.&lt;br /&gt;&lt;/p&gt;&lt;p style="font-family: verdana;" class="MsoNormal"&gt;&lt;br /&gt;Supongo que poco a poco  se irán separando cada vez más la base de datos &lt;a href="http://www.firebirdsql.org/"&gt;Firebird &lt;/a&gt;&lt;span style=""&gt; &lt;/span&gt;e Interbase. Ojala y CodeGear desarrolle un driver para &lt;a href="http://www.firebirdsql.org/"&gt;firebird &lt;/a&gt;ya que muchas de las aplicaciones hechas en delphi y BCB utilizan este servidor SQL.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-3717284233572630955?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/3717284233572630955/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=3717284233572630955' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3717284233572630955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/3717284233572630955'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2008/03/firebird-dbx4-blob-fields.html' title='Firebird DBX4 Blob Fields'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-1207997521151211496</id><published>2008-02-18T21:32:00.000-08:00</published><updated>2008-02-18T21:40:14.954-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sql Server'/><category scheme='http://www.blogger.com/atom/ns#' term='base de datos'/><title type='text'>Reiniciar Identity en MS SQL Server</title><content type='html'>Esto es algo que casi no uso, pero de vez en cuando lo necesito y se me olvida apuntarlo, asi que ahora lo anoto aqui para que no se me olvide:&lt;br /&gt;&lt;br /&gt;DBCC CHECKIDENT («Tabla»&lt;tabla&gt;, RESEED, «Semilla»&lt;valor&gt;);&lt;br /&gt;&lt;br /&gt;por ejemplo reiniciar la semilla en la columna CustomerID en la tabla dbo.Customers seria:&lt;br /&gt;&lt;br /&gt;DBCC CHECKIDENT ('dbo.Customers', RESEED, 1);&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-1207997521151211496?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/1207997521151211496/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=1207997521151211496' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1207997521151211496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1207997521151211496'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2008/02/reiniciar-identity-en-ms-sql-server.html' title='Reiniciar Identity en MS SQL Server'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-7733726271457273608</id><published>2008-02-15T18:55:00.001-08:00</published><updated>2008-02-16T21:46:48.543-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IBExpert'/><category scheme='http://www.blogger.com/atom/ns#' term='Firebird'/><category scheme='http://www.blogger.com/atom/ns#' term='base de datos'/><title type='text'>IBExpert</title><content type='html'>Actualmente estoy usando el servidor SQL &lt;a href="http://www.firebirdsql.org/"&gt;Firebird&lt;/a&gt;, este motor al ser open source no trae una herramienta de interfaz grafica para administración. Hay varias que se pueden usar, pero la que he encontrado mas facil y que se adapta mas a lo que necesito es &lt;a href="http://www.blogger.com/www.ibexpert.com"&gt;IBExpert &lt;/a&gt;. Ademas de que tienen una versión personal gratis.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-7733726271457273608?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/7733726271457273608/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=7733726271457273608' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/7733726271457273608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/7733726271457273608'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2008/02/ibexpert.html' title='IBExpert'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-1813815028824874135</id><published>2007-07-29T20:47:00.000-07:00</published><updated>2008-09-03T18:46:13.499-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Firebird'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='base de datos'/><title type='text'>Firebird Stored Procedures</title><content type='html'>Trabajando con los procedimientos almacenados de firebird. Algo  interesante es la posibilidad de tener columnas con acumulados en los procedimientos, algo que no es facil de lograr con MS SQL Server (a menos que se usen tablas temporables o variables de tipo tabla). Y la posibilidad de ejecutar procedimientos por cada registro.&lt;br /&gt;&lt;br /&gt;Este es un ejemplo de un procedimiento que regresa un dataset con los movimientos de una cuenta, mostrando el saldo en cada registro.&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;CREATE PROCEDURE EDO_CTA(DESDE DATE)&lt;br /&gt;RETURNS(&lt;br /&gt;   FECHA DATE,&lt;br /&gt;   CONCEPTO VARCHAR(50),&lt;br /&gt;   ENTRADA DECIMAL(15, 2),&lt;br /&gt;   SALIDA DECIMAL(15, 2)&lt;br /&gt;   SALDO DECIMAL(15, 2)&lt;br /&gt;)&lt;br /&gt;AS&lt;br /&gt;BEGIN&lt;br /&gt;--Obtenemos el saldo inicial&lt;br /&gt;EXECUTE PROCEDURE GET_SALDO_INICIAL(:DESDE)&lt;br /&gt;RETURNING_VALUES :SALDO;&lt;br /&gt;&lt;br /&gt;FOR SELECT&lt;br /&gt;   FECHA, CONCEPTO, ENTRADA, SALIDA&lt;br /&gt;FROM&lt;br /&gt;   MOVIMIENTOS_CUENTA&lt;br /&gt;WHERE&lt;br /&gt;   FECHA &gt; :DESDE&lt;br /&gt;INTO&lt;br /&gt;   :FECHA, :CONCEPTO, :ENTRADA, :SALIDA&lt;br /&gt;DO BEGIN&lt;br /&gt;   SALDO = SALDO + ENTRADA - SALIDA;&lt;br /&gt;   SUSPEND;&lt;br /&gt;END&lt;br /&gt;END;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Esto ira calculando el saldo por cada registro.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-1813815028824874135?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/1813815028824874135/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=1813815028824874135' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1813815028824874135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/1813815028824874135'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2007/07/firebird-stored-procedures.html' title='Firebird Stored Procedures'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-5946255002181801196</id><published>2007-06-21T22:09:00.000-07:00</published><updated>2007-06-21T22:35:34.286-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Firebird'/><category scheme='http://www.blogger.com/atom/ns#' term='Database'/><category scheme='http://www.blogger.com/atom/ns#' term='base de datos'/><title type='text'>¿Por que Firebird?</title><content type='html'>En el proyecto que estoy trabajando estamos migrando de base a datos desde &lt;a href="http://www.mysql.com/"&gt;MySQL&lt;/a&gt; hacia &lt;a href="http://www.firebirdsql.org/"&gt;Firebird&lt;/a&gt;. El problema con &lt;a href="http://www.mysql.com/"&gt;MySQL &lt;/a&gt;fue que aunque es gratis, no puede ser redistribuido a menos que se pague por cada redistribucion, ademas de que las versiones con las que trabajamos no soportaban llaves foraneas ni procedimientos almecenados.&lt;br /&gt;&lt;br /&gt;Otro motor de base de datos que consideramos fue &lt;a href="http://www.microsoft.com/sql/default.mspx"&gt;MS SQL Server 2005&lt;/a&gt;. Este tiene la ventaja de que lo conocemos bien por haberlo utilizado en la mayoria de los proyectos, pero el problema es el costo de las licencias -&lt;em&gt;En realidad el problema no es el costo de la licencia sino el presupuesto para el proyecto :(&lt;/em&gt; - Pensamos entonces en la version &lt;a href="http://www.microsoft.com/sql/editions/express/default.mspx"&gt;Express&lt;/a&gt;, pero no cuenta con todas las ventajas de la version completa.&lt;br /&gt;&lt;br /&gt;Entonces fue que pensamos en &lt;a href="http://www.firebirdsql.org/"&gt;Firebird&lt;/a&gt;, que es un motor de base de datos en mi opinion mas completo que &lt;a href="http://www.mysql.com/"&gt;MySQL &lt;/a&gt;y comparable con &lt;a href="http://www.microsoft.com/sql/default.mspx"&gt;MS SQL Server&lt;/a&gt; (para aplicaciones medianas), puede ser redistribuido sin restrincciones y el deployment de firebird es mas sencillo que el de MS SQL Server.&lt;br /&gt;&lt;br /&gt;He &lt;a href="http://www.firebirdsql.org/dotnetfirebird/blog/2005/02/embedded-firebird-and-microsoft-sql.html"&gt;aqui &lt;/a&gt;una tabla con comparaciones entre MS SQL Server Express y la version embeded de Firebird.&lt;br /&gt;&lt;br /&gt;Estas son algunas de las razones por las que eleigimos &lt;a href="http://www.firebirdsql.org/"&gt;Firebird&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-5946255002181801196?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/5946255002181801196/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=5946255002181801196' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5946255002181801196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5946255002181801196'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2007/06/por-que-firebird.html' title='¿Por que Firebird?'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-5416226958672647620</id><published>2007-05-19T20:22:00.000-07:00</published><updated>2007-05-25T22:42:27.939-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='programacion'/><category scheme='http://www.blogger.com/atom/ns#' term='C++ Builder'/><title type='text'>De C++Builder a Delphi</title><content type='html'>Estoy trabajando en un proyecto en &lt;a href="http://www.codegear.com/products/delphi/2006"&gt;Delphi &lt;/a&gt;y he tenido la oportunidad de aprender mas del IDE y del lenguaje (Object Pascal). Ya conocia la VCL, por que he trabajado en  C++ Builder.&lt;br /&gt;&lt;br /&gt;Este proyecto me decidí por delphi, ya que al trabajar en &lt;a href="http://www.codegear.com/products/cppbuilder"&gt;C++ Builder &lt;/a&gt;siempre me senti como usuario de segunda comparado con el usuarios de Delphi a los que &lt;a href="http://www.borland.com"&gt;Borland &lt;/a&gt;y ahora &lt;a href="http://www.codegear.com"&gt;CodeGear &lt;/a&gt;se enfocan mas, ademas de que solo estaba utilizando la VCL y no estaba aprovechando el potencial de c++ ni la facilidad de Delphi.&lt;br /&gt;&lt;br /&gt;El lenguaje lo he encontrado muy parecido a C# (no en la sintaxis sino en los conceptos que maneja) se nota que tienen a &lt;a href="http://es.wikipedia.org/wiki/Anders_Hejlsberg"&gt;Anders Hejlsberg&lt;/a&gt; en comun. Asi que casi solo tengo que enfocarme en el cambio de sintaxis lo cual no es gran problema.&lt;br /&gt;&lt;br /&gt;Lo ventaja es que ahora disfruto de todas los avances que tiene el IDE el cual siempre tiene las mejoras primero para delphi que para C++ Builder.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-5416226958672647620?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/5416226958672647620/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=5416226958672647620' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5416226958672647620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/5416226958672647620'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2007/05/de-cbuilder-delphi.html' title='De C++Builder a Delphi'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-117035684970515250</id><published>2007-02-01T10:59:00.000-08:00</published><updated>2007-05-25T22:38:59.808-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sql Server'/><category scheme='http://www.blogger.com/atom/ns#' term='e-mail'/><category scheme='http://www.blogger.com/atom/ns#' term='Database Mail'/><title type='text'>Database Mail en MS SQL Server 2005</title><content type='html'>Configuración de Database Mail en MS SQL Server 2005&lt;br /&gt;&lt;br /&gt;Primero se debe de habilitar, ya que por omisión el componente esta deshabilitado, Utilizando el SSMS (SQL Server Management Studio)&lt;br /&gt;&lt;br /&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/4188/2409/320/299120/dbmailss2.jpg" border="0" /&gt;&lt;br /&gt;Si no esta habilitado aparecerá un mensaje preguntado si lo habilita, después aparece esta ventana donde se pregunta al usuario que es lo desea hacer.&lt;br /&gt;&lt;br /&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/4188/2409/320/327181/dbmailss3.jpg" border="0" /&gt;&lt;br /&gt;Seleccionamos la primera opción para crear un perfil.&lt;br /&gt;&lt;br /&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/4188/2409/320/518995/dbmailss4.jpg" border="0" /&gt;&lt;br /&gt;Configuramos el perfil y le agregamos por lo menos una cuenta.&lt;br /&gt;&lt;br /&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand" alt="" src="http://photos1.blogger.com/x/blogger/4188/2409/320/513368/dbmailss5.jpg" border="0" /&gt;&lt;br /&gt;Seleccionamos el perfil como public y default.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Para mandar correo se utiliza el procedimiento msdb.sp_send_dbmail por lo tanto el usuario que intente mandar correo debe de tener permiso para la base de datos msdb.&lt;br /&gt;&lt;br /&gt;Referencias:&lt;br /&gt;&lt;a href="http://www.sqlservercentral.com/columnists/cBunch/introtodatabasemailinsql2005.asp"&gt;http://www.sqlservercentral.com/columnists/cBunch/introtodatabasemailinsql2005.asp&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-117035684970515250?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/117035684970515250/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=117035684970515250' title='6 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/117035684970515250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/117035684970515250'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2007/02/database-mail-en-ms-sql-server-2005.html' title='Database Mail en MS SQL Server 2005'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-117026369579492362</id><published>2007-01-31T08:54:00.000-08:00</published><updated>2008-09-08T10:41:38.054-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Coca-Cola'/><category scheme='http://www.blogger.com/atom/ns#' term='Trabajo'/><category scheme='http://www.blogger.com/atom/ns#' term='Cdf'/><title type='text'>Cosas que aprendi en Coca-Cola</title><content type='html'>El viernes 2 de febrero es mi último dia como empleado de "Servicios ejecutivos del Noroeste". Gracias a todos por el apoyo que me dieron. Esta es una lista de algunas de las cosa que aprendi trabajando para Sistemas en Cdf (Coca-Cola).&lt;br /&gt;&lt;ul&gt;&lt;li&gt;El que te llames igual que tu superior no significa que lo puedas llamar tocayo&lt;/li&gt;&lt;li&gt;el signo "¿" se pronuncia "Pregunta".&lt;/li&gt;&lt;li&gt;La palabra "interface" o "interfase" no existe (la que existe es interfaz), pero si se usa.&lt;/li&gt;&lt;li&gt;El que haya muchos jefes no significa que exista gente a su cargo (algunos son jefes de ellos mismos solamente)&lt;/li&gt;&lt;li&gt;Solo los chilangos tienen oficina&lt;/li&gt;&lt;li&gt;El vino tinto es bueno para romper el hielo&lt;/li&gt;&lt;li&gt;Pagar derecho de piso es un mito&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Estas son solo algunas, espero despues completar la lista.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-117026369579492362?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/117026369579492362/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=117026369579492362' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/117026369579492362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/117026369579492362'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2007/01/cosas-que-aprendi-en-coca-cola.html' title='Cosas que aprendi en Coca-Cola'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-115708291174039079</id><published>2006-08-31T20:46:00.000-07:00</published><updated>2007-01-31T09:20:14.506-08:00</updated><title type='text'>Vuelven los Turbo</title><content type='html'>&lt;a href="http://www.codegear.com"&gt;CodeGear &lt;/a&gt;- &lt;a href="http://www.borland.com"&gt;Borland &lt;/a&gt;relanza sus productos &lt;a href="http://www.turboexplorer.com"&gt;turbo&lt;/a&gt; (c++, Delphi win32, Delphi.net y c#). Saldran 2 versiones. La version Explorer y la version profesional. tendran las mismas caracteristicas que la version profesional del BDS.&lt;br /&gt;&lt;br /&gt;la version explorer es gratis y se puede usar para realizar aplicaciones comerciales, lo malo es que no se le pueden agregar componentes de terceros ni trae reporteador.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-115708291174039079?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/115708291174039079/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=115708291174039079' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/115708291174039079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/115708291174039079'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2006/08/vuelven-los-turbo.html' title='Vuelven los Turbo'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-115680734101972443</id><published>2006-08-28T16:16:00.001-07:00</published><updated>2010-07-26T11:33:13.547-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Sara Mercedes Cornejo Portillo</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/4188/2409/1600/100_0411.jpg"&gt;&lt;img style="float: right; margin: 0px 0px 10px 10px;" alt="" src="http://photos1.blogger.com/blogger/4188/2409/320/100_0411.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/4188/2409/1600/100_0425.jpg"&gt;&lt;/a&gt;&lt;br /&gt;Ya nació mi hija Sara Mercedes. Una preciosa bebita que nació el 23 de Agosto del 2006 a las 3:45 am y que no me ha dejado dormir desde entonces.&lt;br /&gt;&lt;br /&gt;Peso 3 Kg y midio .51 m&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-115680734101972443?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/115680734101972443/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=115680734101972443' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/115680734101972443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/115680734101972443'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2006/08/sara-mercedes-cornejo-portillo.html' title='Sara Mercedes Cornejo Portillo'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-114601060927875326</id><published>2006-04-25T17:11:00.000-07:00</published><updated>2009-02-03T17:40:13.973-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Crystal Reports'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Cambiar data source de un crystal report en tiempo de ejecucion</title><content type='html'>Para cambiar el servidor, base de datos, user id y password de reportes crystal en tiempo de ejecucion (runtime)  se debe indicar la informacion de la conexion a cada tabla del reporte y tablas de los subreportes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;private bool ApplyLogon(ReportDocument cr, ConnectionInfo ci)&lt;br /&gt;{&lt;br /&gt;TableLogOnInfo li;&lt;br /&gt;// for each table apply connection info&lt;br /&gt;foreach (CrystalDecisions.CrystalReports.Engine.Table tbl in cr.Database.Tables)&lt;br /&gt;{&lt;br /&gt;li = tbl.LogOnInfo;&lt;br /&gt;li.ConnectionInfo = ci;&lt;br /&gt;tbl.ApplyLogOnInfo(li);&lt;br /&gt;// check if logon was successful&lt;br /&gt;// if TestConnectivity returns false, check&lt;br /&gt;// logon credentials&lt;br /&gt;if (tbl.TestConnectivity())&lt;br /&gt;{&lt;br /&gt;// drop fully qualified table location&lt;br /&gt;if (tbl.Location.IndexOf(".") &gt; 0)&lt;br /&gt;tbl.Location = tbl.Location.Substring(tbl.Location.LastIndexOf(".") + 1);&lt;br /&gt;else&lt;br /&gt;tbl.Location = tbl.Location;&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;return false;&lt;br /&gt;}&lt;br /&gt;return true;&lt;br /&gt;}&lt;br /&gt;// El metodo recorre todas las tablas&lt;br /&gt;private bool Logon(ReportDocument cr, string server, string db, string id, string pass)&lt;br /&gt;{&lt;br /&gt;ConnectionInfo ci = new ConnectionInfo();&lt;br /&gt;SubreportObject subObj;&lt;br /&gt;ci.ServerName = server;&lt;br /&gt;ci.DatabaseName = db;&lt;br /&gt;ci.UserID = id;&lt;br /&gt;ci.Password = pass;&lt;br /&gt;if (!ApplyLogon(cr, ci))&lt;br /&gt;return false;&lt;br /&gt;foreach (ReportObject obj in cr.ReportDefinition.ReportObjects)&lt;br /&gt;{&lt;br /&gt;if (obj.Kind == ReportObjectKind.SubreportObject)&lt;br /&gt;{&lt;br /&gt;subObj = (SubreportObject)obj;&lt;br /&gt;if (!ApplyLogon(cr.OpenSubreport(subObj.SubreportName), ci))&lt;br /&gt;return false;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;return true;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-114601060927875326?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/114601060927875326/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=114601060927875326' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/114601060927875326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/114601060927875326'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2006/04/cambiar-data-source-de-un-crystal.html' title='Cambiar data source de un crystal report en tiempo de ejecucion'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23470706.post-114159041376353734</id><published>2006-03-05T12:14:00.000-08:00</published><updated>2006-03-05T12:50:57.793-08:00</updated><title type='text'>Comunidad de Egresados</title><content type='html'>Ya inicio la organización del grupo de egresados de la carrera Ing. En computación de la UABC. La idea es que al principio seamos amigos con reuniones para poder compartir conocimientos, experiencias, técnicas y consejos.&lt;br /&gt;&lt;br /&gt;Espero que no solo se traten temas técnicos, si no también temas relacionados con el trabajo. Para estar todos enterados de como se encuentra la industria en nuestra región, que es lo que se requiere saber y cuanto se debe cobrar o pagar para así ser competitivos.&lt;br /&gt;&lt;br /&gt;Por el momento se ha planteado que las reuniones sean el primer viernes de cada mes en la noche, pero todavía esta por confirmarse, se requiere que los posibles asistentes revisen sus agendas.&lt;br /&gt;&lt;br /&gt;Con este post inicio mi blog; espero mantenerlo actualizado.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23470706-114159041376353734?l=www.developeando.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.developeando.com/feeds/114159041376353734/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23470706&amp;postID=114159041376353734' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/114159041376353734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23470706/posts/default/114159041376353734'/><link rel='alternate' type='text/html' href='http://www.developeando.com/2006/03/comunidad-de-egresados.html' title='Comunidad de Egresados'/><author><name>Mario Cornejo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/-oBZqmGRDwak/TWIPkQuMwuI/AAAAAAAAAOk/4gcu3V58etA/s220/69341_1389519672571_1669494616_885056_6723990_n.jpg'/></author><thr:total>0</thr:total></entry></feed>
