<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"><channel><title>Lucas Ontivero : Patrones</title><link>http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx</link><description>Etiquetas: Patrones</description><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Design patterns in the test of time: VISITOR</title><link>http://geeks.ms/blogs/lontivero/archive/2012/10/30/design-patterns-in-the-test-of-time-visitor.aspx</link><pubDate>Tue, 30 Oct 2012 04:46:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:207265</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=207265</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=207265</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/10/30/design-patterns-in-the-test-of-time-visitor.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://ayende.com/blog/" target="_blank"&gt;@Ayende&lt;/a&gt; ha comenzado una &lt;a href="http://ayende.com/blog/tags/design-patterns-test-of-time" target="_blank"&gt;serie de post en lo que revisa algunos patrones de diseño&lt;/a&gt; (Go4) luego de transcurridos más de 18 años desde su formalización en el libro &lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612" target="_blank"&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/a&gt;.&amp;#160; Inspirado por esa serie, y por el hecho de que en mi última entrevista laboral me preguntaron sobre esto,&amp;#160; voy a presentar una revisión sobre el patrón visitor.&lt;/p&gt;  &lt;h1&gt;&amp;#160;&lt;/h1&gt;  &lt;h1&gt;Visitor en su forma clásica&lt;/h1&gt;  &lt;p&gt;La motivación detrás de este patrón es poder añadir funcionalidad a una estructura de datos sin necesidad de modificar las clases que conforman esa estructura. En otras palabras: separar las estructuras de datos de aquellos algoritmos que operan sobre ellas. Si vamos a la Wikipedia vamos a ver este diagrama:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/commons/5/59/VisitorPatternUML.png" width="640" height="366" alt="" /&gt;    &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:cffd77cf-ec12-4d23-9593-d382195dca33" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Design" rel="tag"&gt;Design&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Pattern" rel="tag"&gt;Pattern&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Visitor" rel="tag"&gt;Visitor&lt;/a&gt;&lt;/div&gt; &lt;/p&gt;  &lt;p&gt;Como se ve, tiene referencias cíclicas, es decir, todos los CarElements deben implementar un método accept que recibe una referencia a un CarElementVisitor y todo CarElementVisitor matiene referencias a todos los tipos que implementan la interface CarElement. Esto es porque C# (el diagrama usa java) no posibilida doble dispatch y así, mediante estas referencias cíclicas es cómo se logra simularla.&lt;/p&gt;  &lt;p&gt;Aparte del fuertísimo acoplamiento al que nos fuerza, tiene el inconveniente de ser un patrón que agrega bastante complejidad y que es poco legible debido a su “extraña” sintaxis. Así, si tuviésemos un AST y quisiésemos volverlo código mediante un visitor, nuestro código se vería así:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_1506DE1F.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="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_10CCE08D.png" width="401" height="31" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Pero si tratamos de seguir este código, y vamos directamente a la implementación de este método ‘Accept’ nos encontraremos con esto:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_16A78426.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="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_7B8EB517.png" width="401" height="74" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Y por último, si nos salteamos la abstracción IVisitor y vamos directamente a la implementación del método Visit del PrinterVisitor, nos encontramos con esto otro:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_0573A683.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="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_2AFD23E4.png" width="401" height="104" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Si no conoces el patrón, posiblemente no comprendas este código (y tengamos en cuenta que nos hemos salteado las abstracciones!). Pero el motivo más frecuente por el que no se entiende, si es ese el caso, es porque es complejo.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Visitor alternativo&lt;/h1&gt;  &lt;p&gt;La propuesta que dejo no es mia, ni es nueva. Esta es una implementación muy popular en lenguajes dinámicos.&lt;/p&gt;  &lt;p&gt;Partamos del mismo supuesto: tenemos un AST al que queremos transformar en un string. Lo primero que podemos cambiar es la sintaxis confuza del visitor clásico mediante el uso de un Extension Method, como sigue:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_4F420866.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="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_161B0597.png" width="401" height="194" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ahora veamos cómo se ven los nodos de este árbol:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_451D416E.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="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_5755E263.png" width="401" height="278" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Si bien aquí tenemos una interface INode la cual no luce muy bien, la simplicidad de los nodos es evidente ya que no estamos forzando a implementar ningún método extraño, me refiero al método ‘Accept’. Peo vamos a ver la implementación:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_680D6744.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="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_75AFFD7F.png" width="583" height="532" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Esta implementación es mucho menos compleja y legible, además de reducir notablemente el acoplamiento (los nodos no necesitan conocer al IVisitor ni implementar ningún método extra) lo que posibilita eliminar las referencias cíclicas. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lucas Ontivero&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207265" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Clean+Code/default.aspx">Clean Code</category></item><item><title>C# Closures y tipos anónimos a la Javascript</title><link>http://geeks.ms/blogs/lontivero/archive/2012/05/24/c-closures-y-tipos-an-243-nimos-a-la-javascript.aspx</link><pubDate>Thu, 24 May 2012 05:13:28 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:205199</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=205199</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=205199</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/05/24/c-closures-y-tipos-an-243-nimos-a-la-javascript.aspx#comments</comments><description>&lt;p&gt;Es C# realmente dinámico? Si hace Cuac es un pato, si hace lo mismo que un lenguaje dinámico es dinámico. Qué te dice este código:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_605E376E.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_57418620.png" width="586" height="590" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=205199" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Infraestructura</title><link>http://geeks.ms/blogs/lontivero/archive/2012/04/17/infraestructura.aspx</link><pubDate>Tue, 17 Apr 2012 19:52:05 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:204516</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=204516</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=204516</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/04/17/infraestructura.aspx#comments</comments><description>&lt;p&gt;Por qué es necesario empujar tantos conceptos a la infaestructura como sea posible.&lt;/p&gt;  &lt;p&gt;&lt;object style="height:390px;width:640px;"&gt;&lt;param name="movie" value="http://www.youtube.com/v/9oSh2IZ88mU?version=3&amp;amp;feature=player_detailpage"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/9oSh2IZ88mU?version=3&amp;amp;feature=player_detailpage" type="application/x-shockwave-flash" allowscriptaccess="always" width="640" height="360"&gt;&lt;/object&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=204516" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Refactoring/default.aspx">Refactoring</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Exceptions/default.aspx">Exceptions</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Clean+Code/default.aspx">Clean Code</category></item><item><title>Patrón repetido en MVC. Mi propuesta</title><link>http://geeks.ms/blogs/lontivero/archive/2012/02/08/patr-243-n-repetido-en-mvc-mi-propuesta.aspx</link><pubDate>Wed, 08 Feb 2012 06:20:43 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203251</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=203251</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=203251</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/02/08/patr-243-n-repetido-en-mvc-mi-propuesta.aspx#comments</comments><description>&lt;p&gt;Cuando usamos ASP.MVC uno de los patrones que debemos respetar es el de “Un modelo entra, un modelo sale” y otro muy común es el de validar el modelo y si este no es válido devolverle la misma vista al usuario para que corrija los datos de entrada. Por esto es común ver el siguiente patrón:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_6921C6C4.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_6A36AFE3.png" width="489" height="179" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;¿Qué está mal aquí? ¿Lo ves?&lt;/p&gt;  &lt;p&gt;Lo que está mal es que este patrón se repite en cada una de las acciones de cada uno de los controladores de cada una de las aplicaciones que hacemos con MVC Framework y eso huele muy pero muy mal (DRY).&lt;/p&gt;  &lt;p&gt;Este es el tipo de casos en los que puede ayudarnos AOP, y MVC framework hace un trabajo espectacular al posibilitarnos implementar AOP mediante filtros. Entonces mi idea es que esto debería hacerse así:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_47263E73.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_22D13424.png" width="462" height="115" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Ahora sí el método hace lo que tiene que hacer, ni más ni menos. Para esto (y solo para demostrar mi punto) he creado el atributo ModelValidationAttribute (necesita un mejor nombre!) como sigue:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_463DB2BC.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_1797840D.png" width="544" height="288" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Y esto funciona a la perfección! Ojo, no recomiendo usarlo sin antes hacer una buena implementación ya que le faltan cosas al ViewResult como TempData entre otras (y el OnActionExecuted vacio tiene un olorcito medio feo – pero no es culpa mia! ¿por qué el creador de la interface IActionFilter me obliga a incumplir el contrato? ¿No serán 2 interfaces distintas [LSP]?)&lt;/p&gt;  &lt;p&gt;Bueno, esto como les dije funciona a la perfección. La prueba:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_71257AF4.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_125570D1.png" width="440" height="80" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Saludos.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203251" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Refactoring/default.aspx">Refactoring</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Clean+Code/default.aspx">Clean Code</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/ASP.MVC/default.aspx">ASP.MVC</category></item><item><title>Refactoring–Extract Method para separar validaciones de operaciones</title><link>http://geeks.ms/blogs/lontivero/archive/2012/01/25/refactoring-extract-method-para-separar-validaciones-de-operaciones.aspx</link><pubDate>Wed, 25 Jan 2012 19:55:59 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:203002</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=203002</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=203002</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/01/25/refactoring-extract-method-para-separar-validaciones-de-operaciones.aspx#comments</comments><description>&lt;p&gt;Existen casos en los que es conveniente extraer un bloque de código en un nuevo método por razones de validaciones de entrada. Es decir, queremos sepaar el código de validaciones de entradas del código que realiza propiamente las operaciones con estas. En algunos casos esto además puede traernos algunos beneficios de performance. Esto es más claro en los métodos recursivos. Para ilustrar esto pongamos como ejemplo al clásico método que calcula el Factorial de N de manera recursiva:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_51537C78.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_2070C50D.png" width="500" height="118" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Aquí el problema está en que el parámetro ‘n’ se valida en cada llamada pero la realidad es que esto no debería ser así ya que si ‘n’ es válido en la primera llamada este va a serlo también en todas las sucesivas invocaciones que se hacen de manera recursiva. Por este motivo es conveniente separar las validaciones y extraer el cálculo del factorial para llevarlo a otro método como sigue:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_45FA426E.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_0EF03E68.png" width="507" height="197" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;No es la performance lo que interesa aquí sino la separación conceptual de las validaciones y las operaciones, el incremento de la performance es solo un producto derivado de haber hecho esto.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=203002" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Refactoring/default.aspx">Refactoring</category></item><item><title>[Video] Serie sobre excepciones–El rol de las interfaces</title><link>http://geeks.ms/blogs/lontivero/archive/2012/01/24/video-serie-sobre-excepciones-el-rol-de-las-interfaces.aspx</link><pubDate>Tue, 24 Jan 2012 04:19:13 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202944</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=202944</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=202944</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/01/24/video-serie-sobre-excepciones-el-rol-de-las-interfaces.aspx#comments</comments><description>&lt;p&gt;Esta es seguramente la última entrada sobre excepciones en la que explico el rol de la interfaces (con el usuario u otro tipo de clientes) en la captura, tratamiento y traducción de las excepciones.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:ff1ef67d-621b-4132-88e1-34f01af68f68" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=8mDyS91WuMY&amp;amp;feature=youtube_gdata_player" target="_new"&gt;&lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/video7a1d1fc217ee_5F00_4FA11921.jpg" style="border-style:none;" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202944" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Series/default.aspx">Series</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Exceptions/default.aspx">Exceptions</category></item><item><title>[Video] Serie sobre excepciones – Explicando ejemplo del MSDN</title><link>http://geeks.ms/blogs/lontivero/archive/2012/01/20/video-serie-sobre-excepciones-explicando-ejemplo-del-msdn.aspx</link><pubDate>Fri, 20 Jan 2012 06:00:07 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202896</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=202896</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=202896</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/01/20/video-serie-sobre-excepciones-explicando-ejemplo-del-msdn.aspx#comments</comments><description>&lt;p&gt;En este video explico el por qué un ejemplo tomado del MSDN está mal y cómo debería de escribirse en cuanto a la manera en que trata las excepciones.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:b242257b-e422-4cf5-8c30-8294f91240cd" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=i8wxG5_7YTc&amp;amp;feature=youtube_gdata_player" target="_new"&gt;&lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/video48922cb81322_5F00_541E2E5B.jpg" style="border-style:none;" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202896" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Series/default.aspx">Series</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Exceptions/default.aspx">Exceptions</category></item><item><title>Excepciones – Un caso sobre los ejemplos del MSDN</title><link>http://geeks.ms/blogs/lontivero/archive/2012/01/20/excepciones-una-caso-sobre-los-ejemplos-del-msdn.aspx</link><pubDate>Fri, 20 Jan 2012 05:25:31 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202895</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=202895</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=202895</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2012/01/20/excepciones-una-caso-sobre-los-ejemplos-del-msdn.aspx#comments</comments><description>&lt;p&gt;Soy un convencido de que muchos de los malentendidos que existen en cuanto al manejo de excepciones en VB.Net y C# es por culpa de los malos ejemplos que siempre ha tenido el MSDN. Con solo invertir un par de segundos en google uno puede encontrar verdaderas aberraciones.. A modo de ejemplo solo pondré dos links y las capturas:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.net.dns.resolve(v=vs.110).aspx"&gt;http://msdn.microsoft.com/en-us/library/system.net.dns.resolve(v=vs.110).aspx&lt;/a&gt;&amp;#160; &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_4C7BD4DA.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin: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="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_4DB047EC.png" width="457" height="366" /&gt;&lt;/a&gt;     &lt;br /&gt;Si Bien es cierto que los ejemplos han mejorado muchísimo, porque años antes eran un desastre, todavía siguen existiendo demasiados de estos ejemplos, ejemplos que son tomados por muchos desarrolladores como “bunas prácticas” ya que provienen de un sitio de la más alta confianza.     &lt;br /&gt;    &lt;br /&gt;Otro ejemplo: &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient(v=vs.110).aspx"&gt;http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient(v=vs.110).aspx&lt;/a&gt;. Hay tantas cosas mal en este que da para pensar si estos ejemplos ayudan a los programadores o si por el contrario, los perjudica.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_028D275D.png"&gt;&lt;img style="background-image:none;border-right-width:0px;margin: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="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_7A192C38.png" width="477" height="707" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202895" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Exceptions/default.aspx">Exceptions</category></item><item><title>[Video] Serie sobre excepciones–Donde capturarlas</title><link>http://geeks.ms/blogs/lontivero/archive/2011/12/19/video-serie-sobre-excepciones-donde-capturarlas.aspx</link><pubDate>Tue, 20 Dec 2011 01:47:03 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202246</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=202246</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=202246</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2011/12/19/video-serie-sobre-excepciones-donde-capturarlas.aspx#comments</comments><description>&lt;p&gt;Les dejo la tercera entrega de la serie sobre excepciones.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:dab7d61a-5f65-4e42-9197-95a1946d6e0b" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=62fuHcYB4Hg&amp;amp;feature=youtube_gdata_player" target="_new"&gt;&lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/videob5ae928734ae_5F00_54E188AE.jpg" style="border-style:none;" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;Saludos&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202246" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Series/default.aspx">Series</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Retoques a MVC y Razor para proyectos grandes–Una recomendación</title><link>http://geeks.ms/blogs/lontivero/archive/2011/12/17/retoques-a-mvc-y-razor-para-proyectos-grandes-una-recomendaci-243-n.aspx</link><pubDate>Sat, 17 Dec 2011 22:28:32 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202190</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=202190</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=202190</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2011/12/17/retoques-a-mvc-y-razor-para-proyectos-grandes-una-recomendaci-243-n.aspx#comments</comments><description>&lt;p&gt;Luego de revisar los requerimientos de la aplicación en la que vengo trabajado estos últimos 6 meses,&amp;#160; tuve que pensar cómo plantear la arquitectura de la misma teniendo en cuenta lo siguiente:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;La aplicación es muy muy muy grande, eso era lo primero que saltaba a la vista en los requerimientos. Al día de hoy, esta cuenta con 1.119 vistas, 797 controladores y un número similar de modelos, entre otras cosas.&lt;/li&gt;    &lt;li&gt;El equipo iba a ser grande y la idea era que trabajaran lo más focalizados posible en sus casos de uso y luego integrarlos para evitar fricción de dependencias entre los diferentes casos de uso.&lt;/li&gt;    &lt;li&gt;La aplicación tiene módulos que agrupan sub-módulos y estos a su vez agrupan casos de uso. Los casos de uso eran bastante similares por lo que era también de esperarse que tuviesen una estructura similar entre ellos. Esto es: Vistas con idénticos o similares nombres como así también controladores y modelos similares los cuales podían también tener el mismo nombre.&lt;/li&gt;    &lt;li&gt;El esquema de seguridad se basa en perfiles de usuarios los cuales tienen permisos sobre distintas operaciones sobre cada uno de esos casos de uso.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Con eso en mente, era evidente que el esquema por defecto de MVC (usando Razor) no era el adecuado ya que, por defecto, este agrupa las vistas en la carpeta Views, controladores en la carpeta Controllers y modelos en la carpeta Models. Es muy difícil de trabajar en un sistema grande con esta estructura; es a todas luces insuficiente ya tener 1.119 vistas en una sola carpeta presenta muchos problemas no solo a la hora de encontrar un archivo sino que además obliga a que no existan dos vista con el mismo nombre y eso era algo que el proyecto necesitaba tener realmente. &lt;/p&gt;  &lt;p&gt;De no plantear una estructura de módulos, sub-módulos y casos de uso adecuada a las necesidades del proyecto este iba a ser un desastre, así que así lo hice. Para esto extendí dos componentes: ControllerFactory y RazorViewEngine.&lt;/p&gt;  &lt;p&gt;Antes de comenzar, y para que vayan dándose una idea, nuestro esquema de mapeo en el Global.asax es el siguiente:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_646432E5.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_1868AC6C.png" width="398" height="68" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Y nuestra estructura de carpetas es la que sigue:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_770906CF.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_0A8640A4.png" width="452" height="547" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;El ControllerFactory (simplificado para este blog) se ve más o menos como figura abajo y nos permite tener clases controladores con el mismo nombre pero con distinto namespace:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_273FB5B9.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_37F73A9A.png" width="662" height="410" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Por otro lado, la organización de las vistas en carpetas módulo/sub-módulo/casodeuso/ se logró extendiendo la clase RazorViewEngine que es la encargada de resolver la ruta donde se deben buscar las vistas cuando desde un controllador se lo solicita. El código de la clase puede verse abajo:   &lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_3BF1629F.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_5243B58C.png" width="815" height="1201" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Con esto no solo se logra que las vistas se busques en la carpeta propia del caso de uso al cual pertenecen sino que además el orden de búsqueda permite que si una vista, layout o template (EditorTemplate o DisplayTemplate) no se encuentra localmente en la carpeta del caso de uso, este busca luego en las vistas del sub-módulo y luego en las vistas del módulo.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Conclusión&lt;/h3&gt;  &lt;p&gt;Dado que ni el ControllerFactory del framework de MVC permite tener controladores con el mismo nombre ni que el esquema de carpetas que por defecto que utiliza RazorViewEngine es suficiente para proyectos realmente grandes, creo que todo proyecto necesita contemplar la conveniencia de, antes de comenzar a desarrollar sus casos de uso, estudiar esta o alguna otra alternativa.&lt;/p&gt;  &lt;p&gt;Yo recomiendo esta solución fuertemente ya que viene dándonos excelentes resultados día tras día y nos ha vuelto la vida increíblemente más sencilla.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202190" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>[Video] Serie sobre excepciones–Malas Prácticas</title><link>http://geeks.ms/blogs/lontivero/archive/2011/12/16/video-serie-sobre-excepciones-malas-pr-225-cticas.aspx</link><pubDate>Fri, 16 Dec 2011 22:50:33 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202177</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=202177</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=202177</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2011/12/16/video-serie-sobre-excepciones-malas-pr-225-cticas.aspx#comments</comments><description>&lt;p&gt;Les dejo la segunda entrega de la serie que estoy desarrollando para el equipo de desarrollo en el cual trabajo. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:b7993089-4262-4773-876a-24dcee398990" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=KR5EYGpyWQ4&amp;amp;feature=youtube_gdata_player" target="_new"&gt;&lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/video2fead9bf9ca3_5F00_206E7404.jpg" style="border-style:none;" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;Saludos &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://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/wlEmoticon_2D00_winkingsmile_5F00_3F44E7E2.png" /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202177" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Series/default.aspx">Series</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>[Video] Serie sobre excepciones–Exceptions vs ErrorCodes</title><link>http://geeks.ms/blogs/lontivero/archive/2011/12/16/video-serie-sobre-excepciones-exceptions-vs-errorcodes.aspx</link><pubDate>Fri, 16 Dec 2011 22:47:42 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202176</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=202176</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=202176</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2011/12/16/video-serie-sobre-excepciones-exceptions-vs-errorcodes.aspx#comments</comments><description>&lt;p&gt;Les dejo el primero de una serie de videos sobre excepciones que estoy creando para el equipo de desarrollo al que pertenezco. Espero les guste.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:b3a768be-6227-4f14-aff9-2c1d9c44f61b" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=RHBe4FNF50k&amp;amp;feature=youtube_gdata_player" target="_new"&gt;&lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/video051bbb3a924d_5F00_57491CA8.jpg" style="border-style:none;" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;Saludos &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://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/wlEmoticon_2D00_winkingsmile_5F00_39776C1C.png" /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202176" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Series/default.aspx">Series</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Cursos/default.aspx">Cursos</category></item><item><title>[Patterns] UnitOfWork</title><link>http://geeks.ms/blogs/lontivero/archive/2011/08/17/patterns-unitofwork.aspx</link><pubDate>Wed, 17 Aug 2011 05:13:21 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:199536</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=199536</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=199536</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2011/08/17/patterns-unitofwork.aspx#comments</comments><description>&lt;div id="msgcns!375AE0CCD1AF61CE!456" class="bvMsg"&gt;   &lt;div align="justify"&gt;Leyendo el artículo de Javier Torrecilla&amp;#160; &lt;a href="http://geeks.ms/blogs/jtorrecilla/archive/2011/08/16/patr-243-n-unit-of-work-iow-o-unidad-de-trabajo.aspx"&gt;Patrón Unit of Work (UoW) o Unidad de Trabajo&lt;/a&gt; me acordé que en 2007 había escrito sobre este patrón y quiero rescatarlo aquí:&lt;/div&gt;    &lt;div align="justify"&gt;&amp;#160;&lt;/div&gt;    &lt;div align="justify"&gt;Este es uno de los patrones más útiles (desde mi punto de vista) con que me he encontrado en el libro &amp;quot;&lt;a href="http://martinfowler.com/books.html#eaa"&gt;Patterns of Enterprise Application Architecture&lt;/a&gt;&amp;quot; (P of EAA) de Martin Fowler. Como dice Martin en su libro &lt;a href="http://martinfowler.com/eaaCatalog/unitOfWork.html"&gt;este patrón:&lt;/a&gt;&lt;/div&gt;    &lt;div align="center"&gt;&amp;quot;Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.&amp;quot;&lt;/div&gt;    &lt;div align="justify"&gt;&lt;/div&gt;    &lt;div align="justify"&gt;&lt;a href="http://martinfowler.com/eaaCatalog/unitOfWorkInterface.gif"&gt;&lt;img border="0" src="http://martinfowler.com/eaaCatalog/unitOfWorkInterface.gif" alt="" /&gt;&lt;/a&gt; &lt;/div&gt;    &lt;div align="justify"&gt;Este patrón se utiliza entonces para trabajar con un conjunto de objetos persistentes que deben tratarse como una &amp;quot;unidad&amp;quot; de trabajo, almacenándose en una base de datos de manera atómica. Este patrón es el encargado de hacer el seguimiento de todos aquellos objetos que son nuevos, y que por lo tanto deben persistirse, todos los objetos que han sido modificados y que deben actualizarse en la base de datos y todos los que han sido borrados y deben quitarse de la base de datos.&lt;/div&gt;    &lt;div align="justify"&gt;&amp;#160;&lt;/div&gt;    &lt;div align="justify"&gt;&lt;/div&gt;    &lt;div align="justify"&gt;Mediante la implementación del patrón UnitOfWork, se logra una disminución de la cantidad de idas y vueltas hacia la base de datos ya que los cambios se realizan por lotes (o unidades de trabajo) redundando en incremento en el rendimiento del sistema porque muchas veces el cuello de botella de las aplicaciones se encuentra en la red de datos. Otro aspecto interesante es que posibilita el esquema de trabajo desconectado con bloqueos optimistas sobre la base de datos, es decir, no se mantienen bloqueados los registros por largos períodos de tiempo sino que se abre una conexión, se inicia una transacción, se hacen los cambios, se hace commit y se libera la conexión todo esto en muy pero muy poco tiempo. &lt;/div&gt;    &lt;div align="justify"&gt;&lt;/div&gt;    &lt;div align="justify"&gt;De ser necesaria la incorporación de un control de concurrencia sobre los registros que serán afectados durante la transacción, de modo de mantener la consistencia de los datos, este patrón nos brinda el ámbito adecuado en donde implementarlo. &lt;/div&gt;    &lt;div align="justify"&gt;Veamos un caso concreto, el famoso ejemplo de la factura. Existe una factura que el usuario debe modificar, entonces traemos desde la base de datos la factura con sus ítems (de factura) cargados, luego, una vez que lo presentamos en pantalla, el usuario hace lo siguiente:&lt;/div&gt;    &lt;ul&gt;     &lt;li&gt;       &lt;div align="justify"&gt;Agrega dos ítems más a la lista de ítems,&lt;/div&gt;     &lt;/li&gt;      &lt;li&gt;       &lt;div align="justify"&gt;Modifica el importe y/o la cantidad de productos de uno de los ítems y finalmente,&lt;/div&gt;     &lt;/li&gt;      &lt;li&gt;       &lt;div align="justify"&gt;Elimina algún que otro ítem.&lt;/div&gt;     &lt;/li&gt;   &lt;/ul&gt;    &lt;p align="justify"&gt;En este caso, cuando deben persistirse los datos? apenas agrega, modifica o elimina un ítem? o debe tratarse a la factura como una unidad y persistir todo junto? Si algo falla,... debe guardarse el resto? que sucede si otro usuario (además del que estamos hablando) estaba trabajando con el mismo documento al mismo tiempo pero guardó primero? como sabemos que fue lo que modificó el usuario y que, por lo tanto, debemos guardar? guardamos primero la factura y luego sus ítems o al revés?&lt;/p&gt;    &lt;p align="justify"&gt;Todas las respuestas a estas preguntas (que considero que las fuiste contestando) se resuelven mediante la implementación de este patrón.&lt;/p&gt;    &lt;p align="justify"&gt;Voy a explicarlo un poco. El Unit Of Work, como se observa en la figura de arriba, se implementa mediante una única clase la cual tendrá al menos tres listas, una lista para los objetos nuevos que deben guardarse en la db, otra lista para los objetos que han sido modificados y que por lo tanto deben modificarse en la db y, otra lista para los objetos que deben eliminarse. Opcionalmente, o mejor dicho, según la implementación lo requiera, puede contener una cuarta lista para almacenar clones de los objetos que se traen desde la base de datos, de manera que antes de persistir un objeto pueda corroborar, mediante estos clones de los objetos originales, que los registros correspondientes no han sido modificados por otro usuario.&lt;/p&gt;    &lt;p align="justify"&gt;Una razón para leer el libro y no solo conformarse con este artículo es que Fowler hace un análisis exhaustivo de este patrón (y de todos sus patrones), sus formas de implementar, cuando implementarlos, pros y contras y sobre todo, lo que a mi más me gustó fueron los distintos intentos por hacer esta clase lo más transparente posible para el programador. Así, por ejemplo, analiza la posibilidad de que todas las clases persistibles hereden de una clase base que automáticamente las registre como nuevas en el contenedor, que cuando se invoque el setter de una propiedad, esta notifique al UnitOfWork correspondiente para que la registre como dirty, etc. &lt;/p&gt;    &lt;p align="justify"&gt;Acá dejo una implementación sencillísima de UnitOfWork sin control de concurrencias y en colaboración con un DataMapper trivial (actualización: el artículo original tenía un proyecto adjunto el cual he perdido, por esta razón el DataMapper no está presente pero lo que originalmente hacía era retornar la sentencia sql necesaria para insertar, modificar y borrar los objetos en la base de datos). &lt;/p&gt;    &lt;p align="justify"&gt;&lt;/p&gt; &lt;/div&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;System;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Collections.Generic;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Text;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Transactions;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Data.SqlClient;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Configuration;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Threading;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Resources;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;ConsoleApplication7;

&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;Patterns
{
    &lt;span style="color:green;"&gt;// Nuestra clase UnitOfWork (Martin Fowler)
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;UnitOfWork
    &lt;/span&gt;{
        &lt;span style="color:green;"&gt;// Aquí estan las tres listas de las que hablamos
        // Ademas de estas puede existir una cuarta que almacene
        // los objetos limpios (o que se leyeron de la db)
        &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IBusinessObject&lt;/span&gt;&amp;gt; newObjects;
        &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IBusinessObject&lt;/span&gt;&amp;gt; dirtyObjects;
        &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IBusinessObject&lt;/span&gt;&amp;gt; removedObjects;

        &lt;span style="color:green;"&gt;// Creamos las listas en este constructor
        &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;UnitOfWork()
        {
            newObjects = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IBusinessObject&lt;/span&gt;&amp;gt;();
            dirtyObjects = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IBusinessObject&lt;/span&gt;&amp;gt;();
            removedObjects = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IBusinessObject&lt;/span&gt;&amp;gt;();
        }

        &lt;span style="color:blue;"&gt;public void &lt;/span&gt;New(&lt;span style="color:#2b91af;"&gt;IBusinessObject &lt;/span&gt;bo)
        {
            Guard.NotNull(Resources.parameter_is_null, &lt;span style="color:#a31515;"&gt;&amp;quot;bo&amp;quot;&lt;/span&gt;, bo);
            Guard.IsTrue(Resources.object_is_dirty, dirtyObjects.Contains(bo));
            Guard.IsTrue(Resources.object_is_deleted, removedObjects.Contains(bo));
            Guard.IsTrue(Resources.object_is_already_inserted, newObjects.Contains(bo));

            newObjects.Add(bo);
        }

        &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Remove(&lt;span style="color:#2b91af;"&gt;IBusinessObject &lt;/span&gt;bo)
        {
            Guard.NotNull(Resources.parameter_is_null, &lt;span style="color:#a31515;"&gt;&amp;quot;bo&amp;quot;&lt;/span&gt;, bo);
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(newObjects.Remove(bo)) &lt;span style="color:blue;"&gt;return&lt;/span&gt;;
            dirtyObjects.Remove(bo);

            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(!removedObjects.Contains(bo))
                removedObjects.Add(bo);
        }

        &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Update(&lt;span style="color:#2b91af;"&gt;IBusinessObject &lt;/span&gt;bo)
        {
            Guard.NotNull(Resources.parameter_is_null, &lt;span style="color:#a31515;"&gt;&amp;quot;bo&amp;quot;&lt;/span&gt;, bo);
            Guard.IsTrue(Resources.object_is_deleted, removedObjects.Contains(bo));

            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(!newObjects.Contains(bo) &amp;amp;&amp;amp; !dirtyObjects.Contains(bo))
                dirtyObjects.Add(bo);
        }

        &lt;span style="color:green;"&gt;// El método Commit es el encargado de iniciar las transacciones,
        // y realizar la invocación a la base de datos.
        &lt;/span&gt;&lt;span style="color:blue;"&gt;public void &lt;/span&gt;Commit()
        {
            &lt;span style="color:blue;"&gt;string &lt;/span&gt;connectString = &lt;span style="color:blue;"&gt;string&lt;/span&gt;.Empty;
            &lt;span style="color:blue;"&gt;using &lt;/span&gt;(TransactionScope transactionScope = &lt;span style="color:blue;"&gt;new &lt;/span&gt;TransactionScope())
            {
                connectString = ConfigurationManager.ConnectionStrings[&lt;span style="color:#a31515;"&gt;&amp;quot;Patterns&amp;quot;&lt;/span&gt;].ConnectionString;

                &lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;SqlConnection &lt;/span&gt;connection = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SqlConnection&lt;/span&gt;(connectString))
                {
                    &lt;span style="color:green;"&gt;// Construimos las sentencias SQL para luego pasárselas a la DB
                    // mediante un command. Para esto, en .Net hay que hacerlo separando
                    // las sentencias con un punto y como (;)
                    &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;StringBuilder &lt;/span&gt;stringBuilder = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;StringBuilder&lt;/span&gt;();

                    &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;IBusinessObject &lt;/span&gt;bo &lt;span style="color:blue;"&gt;in &lt;/span&gt;newObjects)
                        stringBuilder.Append(Mapper.Instance.Insert(bo) + &lt;span style="color:#a31515;"&gt;&amp;quot;;&amp;quot;&lt;/span&gt;);

                    &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;IBusinessObject &lt;/span&gt;bo &lt;span style="color:blue;"&gt;in &lt;/span&gt;dirtyObjects)
                        stringBuilder.Append(Mapper.Instance.Update(bo) + &lt;span style="color:#a31515;"&gt;&amp;quot;;&amp;quot;&lt;/span&gt;);

                    &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;IBusinessObject &lt;/span&gt;bo &lt;span style="color:blue;"&gt;in &lt;/span&gt;removedObjects)
                        stringBuilder.Append(Mapper.Instance.Delete(bo) + &lt;span style="color:#a31515;"&gt;&amp;quot;;&amp;quot;&lt;/span&gt;);

                    &lt;span style="color:blue;"&gt;string &lt;/span&gt;command = stringBuilder.ToString();

                    &lt;span style="color:green;"&gt;// Abre la conexió, crea el comando con las sentencias SQL
                    // e invoca al RDBMS.
                    &lt;/span&gt;connection.Open();
                    &lt;span style="color:#2b91af;"&gt;SqlCommand &lt;/span&gt;command1 = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SqlCommand&lt;/span&gt;(command, connection);
                    command1.ExecuteNonQuery();

                    &lt;span style="color:green;"&gt;// Limpia las listas si todo estuvo bien.
                    &lt;/span&gt;ClearAll();
                }
                transactionScope.Complete();
            }
        }

        &lt;span style="color:blue;"&gt;private void &lt;/span&gt;ClearAll()
        {
            newObjects.Clear();
            dirtyObjects.Clear();
            removedObjects.Clear();
        }
    }
}&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=199536" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>¿Lo que huele mal es la inyección de dependencias?</title><link>http://geeks.ms/blogs/lontivero/archive/2011/04/15/191-lo-que-huele-mal-es-la-inyecci-243-n-de-dependencias.aspx</link><pubDate>Fri, 15 Apr 2011 19:09:32 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:192420</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=192420</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=192420</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2011/04/15/191-lo-que-huele-mal-es-la-inyecci-243-n-de-dependencias.aspx#comments</comments><description>&lt;p&gt;En mi anterior entrada mostraba distintas alternativas que podíamos utilizar para volver al siguiente fragmento de código fácilmente testeable. Obviamente existe una infinidad de alternativas que no he abordado como los frameworks de aislamiento, los servidores de smtp que no envían los mails y muchas más. &lt;/p&gt;  &lt;p&gt;La idea aquí&amp;#160; es mostrar el por qué este código no es un duro de testear. Obviamente es porque tiene una dependencia con la clase SmtpClient la cual se comunica mediante un socket con el ambiente externo.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_74988FF3.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_6444CA4D.png" width="428" height="133" /&gt;&lt;/a&gt;    &lt;br /&gt; Entonces, el problema radica en la sentencia:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_2AC44B07.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_0C799411.png" width="375" height="27" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Ahora bien, en algunos lenguajes como por ejemplo, Ruby. El mismo código es fácilmente testeable ya que las clases e incluso las instancias están abiertas para la modificación en tiempo de ejecución. Entonces en Ruby podemos sobre escribir el método “new” de manera que nos devuelva un tipo diferente al que le pedimos. ¿Podemos en C# hacer lo mismo? Ummm…. la respuesta correcta es no, pero podemos acercarnos bastante. Fijate si notas la diferencia entre el siguiente código y el primero:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_2E64F695.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_795AF815.png" width="430" height="129" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;¿La encontraste? Bien! Este código ahora si es testeable. De la siguiente manera:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_1D16B061.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_4A9A60D5.png" width="465" height="216" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;A simple vista se parece mucho a una sobrecarga del operador “new”, también podría compararse con un contenedor de inversión de control o con una factoría. No es mi intención discutir ese tema sino mostrar como las características nuevas de c# 4 sobre el mundo dinámico nos puede ayudar a pensar en otros tipos de soluciones.&lt;/p&gt;  &lt;p&gt;Les dejo todo el código (es solo una prueba de concepto):&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;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;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System;&lt;/pre&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;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.Net.Mail;&lt;/pre&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;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; CSharpDi&lt;/pre&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;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Program&lt;/pre&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;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;/pre&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;"&gt;        {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;            &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(SmtpClient).RegisterBuilder(p =&amp;gt;&lt;/pre&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;"&gt;                &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;                {&lt;/pre&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;"&gt;                    Send = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Action&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;                    (from, to, subject, body) =&amp;gt; { })&lt;/pre&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;"&gt;                }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;            );&lt;/pre&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;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;            var tm = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TranferManager();&lt;/pre&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;"&gt;            tm.Tranfer();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;        }&lt;/pre&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;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&amp;#160;&lt;/pre&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;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; TranferManager&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    {&lt;/pre&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;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Tranfer()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;        {&lt;/pre&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;"&gt;            &lt;span style="color:#008000;"&gt;// Perform the required actions&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;            var smtpClient = New. SmtpClient();&lt;/pre&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;"&gt;            smtpClient.Send(&lt;span style="color:#006080;"&gt;&amp;quot;info@bank.com&amp;quot;&lt;/span&gt;, &lt;span style="color:#006080;"&gt;&amp;quot;from.Email&amp;quot;&lt;/span&gt;, &lt;span style="color:#006080;"&gt;&amp;quot;Tranfer&amp;quot;&lt;/span&gt;, &lt;span style="color:#006080;"&gt;&amp;quot;?&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;        }&lt;/pre&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;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&amp;#160;&lt;/pre&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;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; New&lt;/pre&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;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; dynamic SmtpClient(&lt;span style="color:#0000ff;"&gt;params&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;[] parameters)&lt;/pre&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;"&gt;        {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(SmtpClient).New(parameters);&lt;/pre&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;"&gt;        }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    }&lt;/pre&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;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; CreationExtensions&lt;/pre&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;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;        &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; Dictionary&amp;lt;Type, Func&amp;lt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;, dynamic&amp;gt;&amp;gt; builders =&lt;/pre&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;"&gt;            &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Dictionary&amp;lt;Type, Func&amp;lt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;, dynamic&amp;gt;&amp;gt;();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&amp;#160;&lt;/pre&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;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; dynamic New(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; Type type, &lt;span style="color:#0000ff;"&gt;params&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;[] parameters)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;        {&lt;/pre&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;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;(builders.ContainsKey(type))&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;                &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; builders[type](parameters);&lt;/pre&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;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Activator.CreateInstance(type, parameters);&lt;/pre&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;"&gt;        }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&amp;#160;&lt;/pre&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;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; RegisterBuilder(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; Type type, Func&amp;lt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;, dynamic&amp;gt; builder)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;        {&lt;/pre&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;"&gt;            builders.Add(type, builder);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;        }&lt;/pre&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;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=192420" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Refactoring/default.aspx">Refactoring</category></item><item><title>¿Como vuelvo testeable mi código? Algo huele mal.</title><link>http://geeks.ms/blogs/lontivero/archive/2011/04/15/191-como-vuelvo-testeable-mi-c-243-digo-algo-huele-mal.aspx</link><pubDate>Fri, 15 Apr 2011 12:07:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:192403</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=192403</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=192403</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2011/04/15/191-como-vuelvo-testeable-mi-c-243-digo-algo-huele-mal.aspx#comments</comments><description>&lt;p&gt;Veamos el siguiente código:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_1464B308.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://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_785684CD.png" width="451" height="159" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Lo que buscamos crear al menos una prueba unitaria para este. ¿Cómo lo hacemos?. Bueno, antes quiero plantear algunos supuestos:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Si bien parece un TransactionScript, hagamos de cuenta que no lo es. El hecho de tener solo un método y ningún campo, propiedad o evento es solo para hacer de este un ejemplo ultra sencillo. Por lo tanto pensemos que sí tiene campos, propiedades y varios métodos. &lt;/li&gt;    &lt;li&gt;Si bien usamos un System.Net.Mail.SmtpClient, la idea es no limitarse solo a esta clase sino que puede ser cualquier otra (en este caso una clase de la BCL). Quizás no tenemos el código para modificarlo (como en este caso) o quizás sí lo tenemos pero modificarlo no es buena idea. &lt;/li&gt;    &lt;li&gt;En principio solo queremos verificar que la transferencia se realiza y NO que el mail se envía correctamente. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Las opciones que analizaremos aquí son:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Inyección de dependencias (DI) &lt;/li&gt;    &lt;li&gt;Sub clasificación &lt;/li&gt;    &lt;li&gt;Decoración &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Inyección de dependencias&lt;/h4&gt;  &lt;p&gt;Usar un Gateway es uno de los caminos más habituales que podemos encontrar para “volver testeable nuestro código”. Hacer esto con el único objetivo de testear el código para mí no solo que no vale la pena sino que es incorrecto. Es una sobre ingeniería, a pequeña escala en este caso, y un despropósito puesto que difícilmente tendremos en el futuro otro tipo de cliente de mail. El único cliente de mail extra existe solo con motivo de testing. Y además tenemos 2 constructores, una interface y una clase extra, etc, etc… horrible. ¡Si tan solo el método Send del SmtpClient fuese virtual!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_75B059CD.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://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_79BD3850.png" width="453" height="295" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Si no quisiéramos pagar ese costo, ahorrarnos la interface y la clase extra pero seguir utilizando la DI como mecanismo, lo que podríamos hacer es darnos una vuelta por el mundo dinámico. Básicamente, cualquier tipo que responda a “Send(string, string, string, string)” nos va a servir.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_7DCA16D3.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://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_1AD2C59C.png" width="440" height="285" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Las dos principales objeciones a esta alternativa vienen de parte de aquellos a quienes les disgustan (¿o asustan?) las implicaciones del chequeo de tipos en tiempo de ejecución como de aquellos a quienes les disgusta el inyectar este tipo de dependencias. Por lo demás, esto facilita bastante la creación de las pruebas. Abajo hay dos pruebas que usan tipos anónimos para realizar dos tipos de pruebas distintas.&lt;/p&gt;  &lt;p&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://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_37DB7464.png" width="507" height="346" /&gt;&lt;/p&gt;  &lt;p&gt;Una solución intermedia entre inyectar tipos estáticos y dinámicos es inyectar acciones. Es decir, inyectar la pieza de código que queremos que se ejecute para enviar los mails como vemos abajo. Esto también facilita enormemente la creación de pruebas y si bien es aceptable, tiene, además del mismo mal olor de todas las alternativas que requieren inyectar dependencias, el problema de ser poco intuitiva. Veamos un ejemplo:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_54E4232C.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://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_2282E05E.png" width="546" height="420" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Conclusión parcial: la inyección de dependencias, en cualquiera de sus formas, nos puede ayudar a crear código más testeable aunque requiere de cierto código extra y ciertos patrones que no siempre redundan en mejor código. Por esta razón, la DI, en casos similares a los de los ejemplos que he presentado, no es una buena alternativa.&lt;/p&gt;  &lt;h4&gt;Sub clasificación&lt;/h4&gt;  &lt;p&gt;Uno podría argumentar que quizás nuestro método Tranfer necesita una pequeña refactorización la cual nos podría ayudar a mejorar el código y de pasada, hacerlo más testeable… veamos:&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://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_2D42C864.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://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_0362542F.png" width="450" height="231" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Ahora podemos crear versiones testeables de esta clase, ya sea a mano o utilizando algún framework de aislamiento. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_2EA97BE7.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://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_6BCD376C.png" width="473" height="247" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Esto parece algo más limpio ¿verdad? No necesitamos extrañas interfaces, constructores, tipos dinámicos ni nada de lo que vimos con anterioridad. Una objeción: ¿qué sucede si la clase necesita ser sealed? Este punto de extensión ha sido creado nuevamente con el único propósito de posibilitar las pruebas porque de lo contrario, el método no sería protected virtual sino simplemente private. Ok, pero es una alternativa válida y nos sirve.&lt;/p&gt;  &lt;h4&gt;Decoración&lt;/h4&gt;  &lt;p&gt;Quizás la responsabilidad de enviar las notificaciones no sea algo propio de nuestra clase TranferManager y por lo tanto podríamos sacar esa responsabilidad a otra clase usando el patrón decorador (o podríamos usar un wrapper también). Veamos:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_6207CFF4.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://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_535FB4C0.png" width="455" height="339" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Ahora podemos testear TranferManager sin dificultades. El problema que se nos presenta ahora es que tal vez lo que necesitamos testear ahora sea la nueva clase TranferManagerWithNotification. &lt;/p&gt;  &lt;p&gt;Esta entrada se ha vuelto muy extensa así que la continuaré más adelante…&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=192403" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Refactoring/default.aspx">Refactoring</category></item><item><title>¿Vale la pena crear pruebas unitarias?</title><link>http://geeks.ms/blogs/lontivero/archive/2011/03/31/191-vale-la-pena-crear-pruebas-unitarias.aspx</link><pubDate>Thu, 31 Mar 2011 16:19:43 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:191387</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>19</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=191387</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=191387</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2011/03/31/191-vale-la-pena-crear-pruebas-unitarias.aspx#comments</comments><description>&lt;p&gt;La creación de pruebas unitarias requiere al menos lo siguiente:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Un framework de pruebas unitarias que debemos dominar. Por lo general son muy simples.&lt;/li&gt;    &lt;li&gt;Código testeable. Típicamente esto implica código susceptible de ser “aislado”.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Nada que decir con respecto al primer punto. Ahora, en cuanto al segundo punto, ¿qué significa que el código pueda ser “aislado”?. Bueno, esto significa que sus dependencias deben poder ser reemplazadas. Esto lo logramos bien por medio de inyectarle sus dependencias o bien utilizando un patrón ServiceLocator (a algún framework con un contenedor de dependencias).&lt;/p&gt;  &lt;p&gt;Entonces, una vez resuelto, necesitamos proveer al código objeto de prueba, dependencias “falsas”. Esto nuevamente requiere o bien que las creemos a manos o que&amp;#160; utilicemos algún isolation framework para crearlas (por lo general en runtime).&lt;/p&gt;  &lt;p&gt;Hasta ahora nada que no sepamos todos ¿verdad? Pero… ¡Vamos de nuevo! Veámoslo en código por favor. Imaginemos que tenemos el siguiente método pero no podemos probarlo porque su dependencia con el LogHelper (una clase con métodos estáticos) nos lo impiden:&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;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;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;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; TransferManager&lt;/pre&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;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Tranfer(Account from, Account to, Money amount)&lt;/pre&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;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;        &lt;span style="color:#008000;"&gt;// Perform the required actions&lt;/span&gt;&lt;/pre&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;"&gt;        LogHelper.Inform(&lt;span style="color:#006080;"&gt;&amp;quot;Done!&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    }&lt;/pre&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;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Si no quisiéramos enredarnos mucho, lo que haríamos sería algo como lo que sigue:&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;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;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;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; TransferManager&lt;/pre&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;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; ILogger _logger;&lt;/pre&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;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; TransferManager(ILogger logger)&lt;/pre&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;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._logger = logger;&lt;/pre&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;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&amp;#160;&lt;/pre&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;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Tranfer(Account from, Account to, Money amount)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    {&lt;/pre&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;"&gt;        &lt;span style="color:#008000;"&gt;// Perform the required actions&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;        _logger.Inform(&lt;span style="color:#006080;"&gt;&amp;quot;Done!&amp;quot;&lt;/span&gt;);&lt;/pre&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;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Y la prueba, se parecería a lo que sigue:&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;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;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;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;[TestMethod]&lt;/pre&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;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Perform_a_valid_tranfer()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;{&lt;/pre&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;"&gt;    var aFakeLogger = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; FakeLogger();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    var tranferManager = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TransferManager(aFakeLogger);&lt;/pre&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;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    &lt;span style="color:#008000;"&gt;// Do and Assert here&lt;/span&gt;&lt;/pre&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;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Lo que falta:&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;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;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;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; ILogger&lt;/pre&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;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Inform(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; messageToLog);&lt;/pre&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;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&amp;#160;&lt;/pre&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;"&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; FakeLogger : ILogger&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;{&lt;/pre&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;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;  Inform(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; messageToLog)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    {&lt;/pre&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;"&gt;        &lt;span style="color:#008000;"&gt;// Nothing to do&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;    }&lt;/pre&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;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;¿Que debimos hacer para probar esa pieza de código? Bueno, varias cosas: en primer lugar fue necesario crear una interface hasta el momento innecesaria (ILogger), tuvimos que agregar un constructor para inyectarle esta dependencia juntamente con un campo para almacenarla; debimos además, y aunque no se muestre aquí, hacer un wrapper para el LogHelper que implemente la interface ILogger. Por otro lado, en el proyecto de prueba, debimos crear una clase falsa (la FakeLogger). &lt;/p&gt;

&lt;p&gt;Creamos FakeLogger de manera manual y con su implementación más sencilla (no hace absolutamente nada) pero bien podríamos haberla creado con un framework de aislamiento y especificarle algún comportamiento.&lt;/p&gt;

&lt;p&gt;Es decir que el código es ahora más complejo que antes ya que tiene, al menos en este ejemplo, un campo más (_logger), un constructor más, una interface más (la ILogger) y una clase más (el wrapper del LogHelper). El código que crea una instancia de esta clase (TranferManager) también se ve afectado. Este es el costo que lleva asociado ineludiblemente el probar, mediante pruebas unitarias, cualquier código.&lt;/p&gt;

&lt;p&gt;Claro, la pregunta es: ¿Valdrá la pena?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=191387" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Productividad/default.aspx">Productividad</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/TDD/default.aspx">TDD</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Refactoring/default.aspx">Refactoring</category></item><item><title>Compiler as a Service – Parte 2</title><link>http://geeks.ms/blogs/lontivero/archive/2011/02/22/compiler-as-a-service-parte-2.aspx</link><pubDate>Tue, 22 Feb 2011 18:34:46 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:189389</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=189389</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=189389</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2011/02/22/compiler-as-a-service-parte-2.aspx#comments</comments><description>&lt;p&gt;Si el compilador de C# pudiera utilizarse como cualquier assembly, podríamos generar código y compilarlo en tiempo de ejecución. Con esto, muchas de las cosas que hoy hacemos mediante CodeDom o Expression trees, las podríamos hacer simplemente concatenando strings (hay maneras mejores). &lt;/p&gt;  &lt;p&gt;Por ejemplo, imaginemos un framework para crear clases Mock al que llamaremos RinhaMock. Aplicaremos este framework en el siguiente test unitario:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;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;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; [TestClass]&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Tests&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt; {&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; It_should_send_messages_with_values()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     {&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         var sentMessage = &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;&amp;#160; &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;         dynamic sender = RinhaMock.Stub&amp;lt;IMessageSender&amp;gt;();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;         sender.When_Send_String = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Action&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;(s =&amp;gt; sentMessage = s);&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;         var transacionManager = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TransactionManager(sender);&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;         transacionManager.Deposit(amount: 50m, accountNo: &lt;span style="color:#006080;"&gt;&amp;quot;0087623481743&amp;quot;&lt;/span&gt;, concept: &lt;span style="color:#006080;"&gt;&amp;quot;Pago cuota&amp;quot;&lt;/span&gt;); &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;&amp;#160; &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;         Assert.AreEqual(&lt;span style="color:#006080;"&gt;&amp;quot;50;0087623481743;Pago cuota&amp;quot;&lt;/span&gt;, sentMessage);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;     }&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;La idea es crear dinámicamente un tipo que implemente la interface IMessageSender y cuyo comportamiento pueda ser especificado fácilmente. Para que el ejemplo sea bien sencillo, vamos a tener una interface IMessageSender con solo un método y una clase TransactionManager igualmente simple:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;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;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; IMessageSender&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Send(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; message);&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; TransactionManager&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt; {&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; IMessageSender _messageSender;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;&amp;#160; &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; TransactionManager(IMessageSender messageSender)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     {&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;._messageSender = messageSender;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;     }&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Deposit(&lt;span style="color:#0000ff;"&gt;decimal&lt;/span&gt; amount, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; accountNo, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; concept)&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;// Do the deposit here&lt;/span&gt;&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;         var message = &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;{0};{1};{2}&amp;quot;&lt;/span&gt;, amount, accountNo,concept);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;         _messageSender.Send(message);&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum21"&gt;  21:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Ahora, la clase stub podría ser escrita por nuestras propias manos, como abajo:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;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;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Stub__IMessageSender : CSharp5.IMessageSender &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; { &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Action&amp;lt;System.String&amp;gt; When_Send_String { get; set; }&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Send ( System.String message ) &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     {  &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         When_Send_String(message); &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;     }&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;O bien se podría&amp;#160; creada a partir de la metadata de la interface IMessageSender y compilada en tiempo de ejecución. Esta última opción, que hoy tenemos con CodeDom, podría ser mucho más rápida y sencilla si el compilador de C# estuviera disponible como un assembly.&lt;/p&gt;

&lt;p&gt;El código necesario para crear el código de la clase stub es el siguiente:
  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;div id="codeSnippetWrapper"&gt;
    &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;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;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; RinhaMock&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; T Stub&amp;lt;T&amp;gt;() &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; T : &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         var typeOfT = &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(T);&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; stubName = &lt;span style="color:#006080;"&gt;&amp;quot;Stub__&amp;quot;&lt;/span&gt; + typeOfT.Name;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         var sb = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; StringBuilder();&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;         var methods = typeOfT&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;             .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod)&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;             .Where(m =&amp;gt; (m.IsVirtual || m.IsAbstract) &amp;amp;&amp;amp; !m.IsSpecialName &amp;amp;&amp;amp; !m.IsFinal);&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;         methods.ForEach(m =&amp;gt; sb.AppendLine(GetConfigPropertyCode(m)));&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;         methods.ForEach(m =&amp;gt; sb.AppendLine(GetMethodCode(m)));&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;         var scripRunner = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ScriptRunner(typeOfT);&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;         var results = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&amp;gt;();&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;         scripRunner.AddObject&amp;lt;Dictionary&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;(&lt;span style="color:#006080;"&gt;&amp;quot;results&amp;quot;&lt;/span&gt;, results);&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;         scripRunner.AddUsing(&lt;span style="color:#006080;"&gt;&amp;quot;CSharp5&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;         scripRunner.AddTypeCode(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;public class {0} : {1} {{ {2} }}&amp;quot;&lt;/span&gt;, stubName, typeOfT.FullName, sb.ToString()));&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt;         scripRunner.AddCode(&lt;span style="color:#006080;"&gt;&amp;quot;results[\&amp;quot;stub\&amp;quot;] = new &amp;quot;&lt;/span&gt; + stubName + &lt;span style="color:#006080;"&gt;&amp;quot;();&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum21"&gt;  21:&lt;/span&gt;         scripRunner.Run();&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum22"&gt;  22:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum23"&gt;  23:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (T)results[&lt;span style="color:#006080;"&gt;&amp;quot;stub&amp;quot;&lt;/span&gt;];&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum24"&gt;  24:&lt;/span&gt;     }&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum25"&gt;  25:&lt;/span&gt;&amp;#160; &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum26"&gt;  26:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; GetMethodCode(MethodInfo method)&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum27"&gt;  27:&lt;/span&gt;     {&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum28"&gt;  28:&lt;/span&gt;         var isProcedure = method.ReturnType == &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;);&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum29"&gt;  29:&lt;/span&gt;         var parameters = method.GetParameters();&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum30"&gt;  30:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum31"&gt;  31:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;public {6} {0} {1} ( {2} ) {{ {3} When_{1}{5}({4}); }}&amp;quot;&lt;/span&gt;,&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum32"&gt;  32:&lt;/span&gt;             isProcedure ? &lt;span style="color:#006080;"&gt;&amp;quot;void&amp;quot;&lt;/span&gt; : method.ReturnType.FullName,&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum33"&gt;  33:&lt;/span&gt;             method.Name,&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum34"&gt;  34:&lt;/span&gt;             parameters.Select(p =&amp;gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Concat(p.ParameterType.FullName, &lt;span style="color:#006080;"&gt;&amp;quot; &amp;quot;&lt;/span&gt;, p.Name)).ToStringList(),&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum35"&gt;  35:&lt;/span&gt;             isProcedure ? &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Empty : &lt;span style="color:#006080;"&gt;&amp;quot;return&amp;quot;&lt;/span&gt;,&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum36"&gt;  36:&lt;/span&gt;             parameters.Select(p =&amp;gt; p.Name).ToStringList(),&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum37"&gt;  37:&lt;/span&gt;             parameters.Any() &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum38"&gt;  38:&lt;/span&gt;                 ? &lt;span style="color:#006080;"&gt;&amp;quot;_&amp;quot;&lt;/span&gt; + parameters.Select(p =&amp;gt; p.ParameterType.Name.Replace(&lt;span style="color:#006080;"&gt;&amp;quot;[]&amp;quot;&lt;/span&gt;, &lt;span style="color:#006080;"&gt;&amp;quot;Array&amp;quot;&lt;/span&gt;)).ToStringList(&lt;span style="color:#006080;"&gt;&amp;quot;_&amp;quot;&lt;/span&gt;) &lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum39"&gt;  39:&lt;/span&gt;                 : &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Empty,&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum40"&gt;  40:&lt;/span&gt;             method.DeclaringType.IsInterface ? &lt;span style="color:#006080;"&gt;&amp;quot;&amp;quot;&lt;/span&gt; : &lt;span style="color:#006080;"&gt;&amp;quot;override&amp;quot;&lt;/span&gt;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum41"&gt;  41:&lt;/span&gt;             );&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum42"&gt;  42:&lt;/span&gt;     }&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum43"&gt;  43:&lt;/span&gt;&amp;#160; &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum44"&gt;  44:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; GetConfigPropertyCode(MethodInfo method)&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum45"&gt;  45:&lt;/span&gt;     {&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum46"&gt;  46:&lt;/span&gt;         var isProcedure = method.ReturnType == &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;);&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum47"&gt;  47:&lt;/span&gt;         var parameters = method.GetParameters();&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum48"&gt;  48:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum49"&gt;  49:&lt;/span&gt;         var methodReturnedType = isProcedure ? &lt;span style="color:#006080;"&gt;&amp;quot;void&amp;quot;&lt;/span&gt; : method.ReturnType.FullName;&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum50"&gt;  50:&lt;/span&gt;         var parametersType = parameters.Select(p =&amp;gt; p.ParameterType);&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum51"&gt;  51:&lt;/span&gt;         var returnedSign = isProcedure ? &lt;span style="color:#006080;"&gt;&amp;quot;Action&amp;lt;{0}&amp;gt;&amp;quot;&lt;/span&gt; :&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum52"&gt;  52:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;Func&amp;lt;{0}{1}&amp;gt;&amp;quot;&lt;/span&gt;, &lt;span style="color:#006080;"&gt;&amp;quot;{0}&amp;quot;&lt;/span&gt;, (parametersType.Any() ? &lt;span style="color:#006080;"&gt;&amp;quot;,&amp;quot;&lt;/span&gt; : &lt;span style="color:#006080;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;) + methodReturnedType);&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum53"&gt;  53:&lt;/span&gt;         var parametersForSign = parametersType.Select(t =&amp;gt; t.Name.Replace(&lt;span style="color:#006080;"&gt;&amp;quot;[]&amp;quot;&lt;/span&gt;, &lt;span style="color:#006080;"&gt;&amp;quot;Array&amp;quot;&lt;/span&gt;)).ToStringList(&lt;span style="color:#006080;"&gt;&amp;quot;_&amp;quot;&lt;/span&gt;);&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum54"&gt;  54:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum55"&gt;  55:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;public {0} When_{1}{2} {{ get; set; }}&amp;quot;&lt;/span&gt;,&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum56"&gt;  56:&lt;/span&gt;             isProcedure &amp;amp;&amp;amp; !parameters.Any() &lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum57"&gt;  57:&lt;/span&gt;                 ? &lt;span style="color:#006080;"&gt;&amp;quot;Action&amp;quot;&lt;/span&gt; &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum58"&gt;  58:&lt;/span&gt;                 : &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(returnedSign, parametersType.Select(t =&amp;gt; t.FullName).ToStringList()),&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum59"&gt;  59:&lt;/span&gt;             method.Name,&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum60"&gt;  60:&lt;/span&gt;             parametersType.Any() ? &lt;span style="color:#006080;"&gt;&amp;quot;_&amp;quot;&lt;/span&gt; + parametersForSign : &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Empty);&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum61"&gt;  61:&lt;/span&gt;     }&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum62"&gt;  62:&lt;/span&gt; }&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum63"&gt;  63:&lt;/span&gt;&amp;#160; &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum64"&gt;  64:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; StringListExtensions&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum65"&gt;  65:&lt;/span&gt; {&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum66"&gt;  66:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; ToStringList(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt; enumerable, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; separator = &lt;span style="color:#006080;"&gt;&amp;quot;, &amp;quot;&lt;/span&gt;)&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum67"&gt;  67:&lt;/span&gt;     {&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum68"&gt;  68:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!enumerable.Any())&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum69"&gt;  69:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Empty;&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum70"&gt;  70:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum71"&gt;  71:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; enumerable.Aggregate((s1, s2) =&amp;gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Concat(s1, separator, s2));&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum72"&gt;  72:&lt;/span&gt;     }&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum73"&gt;  73:&lt;/span&gt; }&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum74"&gt;  74:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum75"&gt;  75:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; IEnumerableExtensions&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum76"&gt;  76:&lt;/span&gt; {&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum77"&gt;  77:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ForEach&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; enumerable, Action&amp;lt;T&amp;gt; action)&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum78"&gt;  78:&lt;/span&gt;     {&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum79"&gt;  79:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var t &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; enumerable) action(t);&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum80"&gt;  80:&lt;/span&gt;     }&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum81"&gt;  81:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
  &lt;/div&gt;

  &lt;p&gt;Como se puede ver, esta podría ser una alternativa viable a todos esos frameworks para la creación de clases proxies como Castle.DynamicProxy (usado por RhinoMocks).&lt;/p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=189389" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/TDD/default.aspx">TDD</category></item><item><title>Compiler as a Service – Parte 1</title><link>http://geeks.ms/blogs/lontivero/archive/2011/02/22/compiler-as-a-service-parte-1.aspx</link><pubDate>Tue, 22 Feb 2011 15:31:55 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:189381</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=189381</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=189381</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2011/02/22/compiler-as-a-service-parte-1.aspx#comments</comments><description>&lt;p&gt;Pensaba acerca de las cosas que podríamos hacer si el compilador de C# fuese un assembly reutilizable (Compilar as a service). Lo primero, y menos original, que se me ocurrió es que podríamos tener algo como JSON pero para C# en lugar de Java Script.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;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;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Program&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;[] args)&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; data = &lt;span style="color:#006080;"&gt;@&amp;quot;results[&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;professional&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;] = &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         new&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         {&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;             FirstName = &amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;Juan Pablo&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;             LastName = &amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;Ibañez&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;,&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;             Certifications = new[]&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;             {&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;                 new { Provider=&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;MSFT&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;, ExamCode = &amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;70-536&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;, Title = &amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;Application Development Foundation&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot; },&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;                 new { Provider=&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;MSFT&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;, ExamCode = &amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;70-505&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;, Title = &amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;Application Development Foundation&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot; },&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;                 new { Provider=&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;MSFT&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;, ExamCode = &amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;70-563&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;, Title = &amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;Application Development Foundation&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;             },&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;             &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;             SayHi = new System.Action(()=&amp;gt; System.Console.WriteLine(&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;Hi&amp;quot;&lt;/span&gt;&lt;span style="color:#006080;"&gt;&amp;quot;))&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;         };&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;&amp;#160; &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt;         dynamic professional = CSharpEvaluator.Evaluate(data)[&lt;span style="color:#006080;"&gt;&amp;quot;professional&amp;quot;&lt;/span&gt;];&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum21"&gt;  21:&lt;/span&gt;         &lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum22"&gt;  22:&lt;/span&gt;         Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;First Name: {0}&amp;quot;&lt;/span&gt;, professional.FirstName);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum23"&gt;  23:&lt;/span&gt;         Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Last Name : {0}&amp;quot;&lt;/span&gt;, professional.LastName);&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum24"&gt;  24:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var certification &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; professional.Certifications)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum25"&gt;  25:&lt;/span&gt;         {&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum26"&gt;  26:&lt;/span&gt;             Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;\tCertification: {0}&amp;quot;&lt;/span&gt;, certification.Title);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum27"&gt;  27:&lt;/span&gt;         }&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum28"&gt;  28:&lt;/span&gt;         professional.SayHi();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;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;"&gt;&lt;span style="color:#606060;" id="lnum29"&gt;  29:&lt;/span&gt;     }&lt;/pre&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;"&gt;&lt;span style="color:#606060;" id="lnum30"&gt;  30:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_2727492D.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://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/lontivero/image_5F00_thumb_5F00_7A347702.png" width="680" height="283" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Esto abriría realmente muchas posibilidades. Una de las que me atrae más es el sustituir los XMLs. Quizás para guardarlos en una base de datos como entidades completas y hacerlas viajar por la red.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=189381" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Investigaciones/default.aspx">Investigaciones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Otro ejemplo de DSL en el mundo real</title><link>http://geeks.ms/blogs/lontivero/archive/2010/08/27/otro-ejemplo-de-dsl-en-el-mundo-real.aspx</link><pubDate>Fri, 27 Aug 2010 03:31:44 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:181154</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=181154</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=181154</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2010/08/27/otro-ejemplo-de-dsl-en-el-mundo-real.aspx#comments</comments><description>Desarrollo un sistema para la planificación, ejecución y seguimiento de encuestas en el que uno de los requerimientos es poder crear encuestas de manera sencilla y veloz. Además las mismas deben seguir un workflow (algo informal) de revisión. Otro dato importante es que el cliente diseña encuestas que van desde aquellas con solo algunas pocas preguntas hasta esas otras que nos tienen todo un domingo respondiendo acerca de alguna ginebra o algún nuevo centro comercial. Para rematar debo decir que...(&lt;a href="http://geeks.ms/blogs/lontivero/archive/2010/08/27/otro-ejemplo-de-dsl-en-el-mundo-real.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=181154" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Software+Factories/default.aspx">Software Factories</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Dise_26002300_241_3B00_o/default.aspx">Dise&amp;#241;o</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Languages/default.aspx">Languages</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Gesti_26002300_243_3B00_n+de+proyectos/default.aspx">Gesti&amp;#243;n de proyectos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Productividad/default.aspx">Productividad</category></item><item><title>Cómo afectan los Mock frameworks nuestras pruebas unitarias</title><link>http://geeks.ms/blogs/lontivero/archive/2010/08/21/c-243-mo-afectan-los-mock-frameworks-nuestras-pruebas-unitarias.aspx</link><pubDate>Sat, 21 Aug 2010 20:24:41 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:180973</guid><dc:creator>Lucas Ontivero</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/rsscomments.aspx?PostID=180973</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/lontivero/commentapi.aspx?PostID=180973</wfw:comment><comments>http://geeks.ms/blogs/lontivero/archive/2010/08/21/c-243-mo-afectan-los-mock-frameworks-nuestras-pruebas-unitarias.aspx#comments</comments><description>Una de las características más importante que debe seguir cualquier código y que es particularmente importante en las pruebas de cualquier tipo es la claridad. Una prueba debe entenderse a la primera sin demasiado esfuerzo, por eso es que debe ser breve, clara y desprovista en el mayor grado posible de elementos ‘ruidosos’. Uno de esos factores ruidosos son los frameworks de aislamiento, los mal llamados Mocking Frameworks. Es por esto que limitar su uso a aquellas ocasiones verdaderamente justificables...(&lt;a href="http://geeks.ms/blogs/lontivero/archive/2010/08/21/c-243-mo-afectan-los-mock-frameworks-nuestras-pruebas-unitarias.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=180973" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/.Net/default.aspx">.Net</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Patrones/default.aspx">Patrones</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Desarrollo/default.aspx">Desarrollo</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/Conceptos/default.aspx">Conceptos</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/XP/default.aspx">XP</category><category domain="http://geeks.ms/blogs/lontivero/archive/tags/TDD/default.aspx">TDD</category></item></channel></rss>