﻿<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel>
    <title>Avanzis (Noticias y Blogs)</title>
    <description>Avanzis (Noticias y Blogs)</description>
    <link>http://www.avanzis.com/rssfeed/122/851.xml</link>
    <lastBuildDate>Tue, 25 Nov 2008 17:24:51 GMT</lastBuildDate>
    <item>
      <title>Adelgazar es bueno</title>
      <description>&lt;p&gt;Todos sabemos que una de las facetas importantes para conservar nuestra salud es mantenernos en un peso equilibrado. Pues en las empresas, también es importante. Y en particular en las empresas de software.&lt;/p&gt;
&lt;p&gt;En los inicios de cualquier empresa, se tiende a pensar, que cuanto más de todo, mejor. &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Cuantos más productos y servicios desarrollemos, más ventas conseguiremos.  &lt;/li&gt;
    &lt;li&gt;Cuantos más clientes y proyectos tengamos, mayores beneficios. &lt;/li&gt;
    &lt;li&gt;Cuanta más complejidad y más líneas de código tengan nuestros programas, mejor, porque significará que tienen más funcionalidades. &lt;/li&gt;
    &lt;li&gt;Cuantos más procesos y procedimientos regulemos, mejor definiremos el funcionamiento de la empresa. &lt;/li&gt;
    &lt;li&gt;Cuantos más trabajadores seamos, mejor podremos asumir grandes cargas de trabajo. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sin embargo, la experiencia de los años y el sentido común, van indicando que no es así. Que conviene no engordar más y adelgazar en lo que sea posible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No hay que desarrollar todos los productos y servicios que se nos ocurran&lt;/strong&gt;. Centrémonos en aquellos que pensemos que pueden ser realmente rentables. Seamos buenos en lo que hacemos, y no mediocres en todo. Especialización y diferenciación de la competencia. Desarrollar un nuevo producto tiene unos costes, y requiere una inversión, pero mantenerlo puede ser un coste oculto mucho mayor de lo esperado. Nos sentiremos tentados a ofrecer servicios complementarios a los que venimos ofreciendo, pero tal vez, sea mejor orientar a nuestros clientes hacia las empresas que pueden satisfacerles esas necesidades mejor que nosotros. Solo deberemos prestar nosotros el servicio si realmente queremos dedicarnos a ello en cuerpo y alma. Si forma parte de nuestra idea de negocio.&lt;/p&gt;
&lt;p&gt;No es necesario tener una amplia cartera de clientes. &lt;strong&gt;Seleccionemos a los clientes y los proyectos que realizamos&lt;/strong&gt;. Es un error aceptar el desarrollo de cualquier proyecto que nos proponga un cliente. Puede resultar apetecible en un primer momento, pero a la larga se paga.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Intentemos mantener nuestras aplicaciones con la mayor simplicidad y la menor cantidad de líneas de código posible&lt;/strong&gt;. Reutilicemos al máximo, y no reinventemos la rueda. Utilicemos frameworks ya existentes y componentes estándares. El mejor programador sería que el consiguiese la funcionalidad deseada sin programar nada. Tras algunos meses o años de desarrollo de una aplicación, tal vez nos encontremos utilizando más tiempo en refactorizar y eliminar código y reemplazando código propio por soluciones existentes, que desarrollando cosas nuevas.&lt;/p&gt;
&lt;p&gt;No tratemos de regular excesivamente con procesos y procedimientos la actividad de la empresa. &lt;strong&gt;Intentemos eliminar al máximo estos procesos automatizándolos&lt;/strong&gt;. La mejor manera de hacer cumplir un procedimiento es que no exista otra manera de hacerlo, o que esté tan automatizado que el proceso como tal quede oculto. Fomentar una cultura y un know-how que permita como realizar una tarea aunque no esté explicitado como realizarla.&lt;/p&gt;
&lt;p&gt;En la mayoría de proyectos, incrementar el número de personas dedicadas al mismo, no produce un incremento lineal del rendimiento ni de la velocidad de desarrollo. No tendamos a incrementar nuestra plantilla como la panacea para asumir mayor carga de trabajo. Seamos eficientes, que nuestra plantilla esté motivada y sea competente en su trabajo. &lt;strong&gt;Mejoremos la productividad&lt;/strong&gt;, busquemos maneras de hacer el mismo trabajo en menor tiempo. Tengamos las herramientas de trabajo adecuadas, investiguemos en nuevas tecnologías que nos permitan una mayor agilidad. La productividad es la clave.&lt;/p&gt;
&lt;p&gt;Resumiendo, &lt;strong&gt;menos es más&lt;/strong&gt;. El ser humano tiende al caos, a la sobrecarga, al barroquismo y al exceso. Adelgazar es una tarea costosa y que requiere esfuerzo. Pero la obesidad es la principal causa de muerte en los países desarrollados. Quizá también de muchas empresas.&lt;/p&gt;
</description>
      <link>http://www.avanzis.com/blogs/josep-planells/i/10418/834/adelgazar-es-bueno</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/josep-planells/i/10418/834/adelgazar-es-bueno</guid>
      <pubDate>Tue, 25 Nov 2008 17:24:51 GMT</pubDate>
    </item>
    <item>
      <title>Utilizar Rhino Mocks y StructureMap en pruebas unitarias con NUnit</title>
      <description>En el posts anteriores ya vimos cómo &lt;strong&gt;utilizar y configurar StructureMap&lt;/strong&gt; para poner en práctica la inyección de dependencias.&lt;br /&gt;
&lt;br /&gt;
Tal y como prometí, ahora vamos a ver un pequeño ejemplo de cómo utilizar el StructureMap y el mocking de objetos en las pruebas unitarias.&lt;br /&gt;
&lt;br /&gt;
Quizá te preguntes que es un “&lt;strong&gt;Mock&lt;/strong&gt;”.&lt;br /&gt;
&lt;br /&gt;
Un mock, en el contexto de pruebas unitarias, es un objeto “falso” que simula el comportamiento del objeto real, con el fin de realizar las pruebas. En la &lt;a title="Definición de Mock" href="http://en.wikipedia.org/wiki/Mock_object"&gt;wikipedia &lt;/a&gt;lo asimilan al maniquí que utilizan los diseñadores coches para realizar las pruebas de accidentes. &lt;br /&gt;
&lt;br /&gt;
Te sugiero si utilizas pruebas unitarias, profundices más sobre este tema.&lt;br /&gt;
Existen muchas librerías para realizar mocks en .NET.&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;
    &lt;a title="Mock en .NET con Rhino Mocks" href="http://ayende.com/projects/rhino-mocks.aspx"&gt;&lt;strong&gt;Rhino Mocks&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;
    &lt;strong&gt;&lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;&lt;a href="http://www.nmock.org/"&gt;NMock&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
En el ejemplo que voy a plantear utilizaré &lt;strong&gt;&lt;a href="hhttp://ayende.com/projects/rhino-mocks.aspx"&gt;Rhino Mocks&lt;/a&gt;&lt;/strong&gt;, para crear un mock de un servicio de mensajería, ya que no quiero que realmente se envíe el correo electrónico al usuario, simplemente quiero probar que el método se llama convenientemente.&lt;br /&gt;
&lt;br /&gt;
Primero crearé la interfaz de este servicio de mensajería.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background: white none repeat scroll 0% 0%; font-family: courier new; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    1&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;interface&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;IMessagingService&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    2&lt;/span&gt; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    3&lt;/span&gt;     &lt;span style="color: blue;"&gt;void&lt;/span&gt; SendMessage(&lt;span style="color: rgb(43, 145, 175);"&gt;User&lt;/span&gt; user, &lt;span style="color: blue;"&gt;string&lt;/span&gt; text);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    4&lt;/span&gt; }&lt;/p&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
En la aplicación “real”, no en las pruebas unitarias, configuraré StructureMap para que el servicio de mensajería sea una implementación de esta interfaz para enviar correos electrónicos. Pero podría ser cualquier otra cosa, enviar SMS, un texto al Messenger, etc…&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background: white none repeat scroll 0% 0%; font-family: courier new; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    1&lt;/span&gt; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ConfigureStructureMap()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    2&lt;/span&gt; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    3&lt;/span&gt;     &lt;span style="color: rgb(43, 145, 175);"&gt;ObjectFactory&lt;/span&gt;.Configure(s =&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    4&lt;/span&gt;         s.BuildInstancesOf&lt;&lt;span style="color: rgb(43, 145, 175);"&gt;IMessagingService&lt;/span&gt;&gt;()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    5&lt;/span&gt;         .TheDefaultIsConcreteType&lt;&lt;span style="color: rgb(43, 145, 175);"&gt;EmailMessagingService&lt;/span&gt;&gt;());&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    6&lt;/span&gt; }&lt;/p&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
El controlador de &lt;strong&gt;&lt;a href="http://www.asp.net/mvc/" target="_blank" title="ASP.NET MVC - Model View Controller"&gt;asp.net mvc&lt;/a&gt;&lt;/strong&gt; que queremos probar tiene la siguiente acción:&lt;br /&gt;
 &lt;br /&gt;
&lt;div style="background: white none repeat scroll 0% 0%; font-family: courier new; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    1&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ActionResult&lt;/span&gt; CreateUser(&lt;span style="color: blue;"&gt;string&lt;/span&gt; userName, &lt;span style="color: blue;"&gt;string&lt;/span&gt; password, &lt;span style="color: blue;"&gt;string&lt;/span&gt; email)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    2&lt;/span&gt; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    3&lt;/span&gt;     &lt;span style="color: rgb(43, 145, 175);"&gt;User&lt;/span&gt; user = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;User&lt;/span&gt;{UserName = userName, Password = password, Email = email};&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    4&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    5&lt;/span&gt;     &lt;span style="color: rgb(43, 145, 175);"&gt;UserValidationResult&lt;/span&gt; result = userService.Register(user);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    6&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    7&lt;/span&gt;     &lt;span style="color: blue;"&gt;if&lt;/span&gt; (result.IsValid)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    8&lt;/span&gt;     {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    9&lt;/span&gt;         &lt;span style="color: rgb(43, 145, 175);"&gt;IMessagingService&lt;/span&gt; messagingService = &lt;span style="color: rgb(43, 145, 175);"&gt;ObjectFactory&lt;/span&gt;.GetInstance&lt;&lt;span style="color: rgb(43, 145, 175);"&gt;IMessagingService&lt;/span&gt;&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   10&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   11&lt;/span&gt;         messagingService.SendMessage(user, &lt;span style="color: rgb(163, 21, 21);"&gt;"Tu cuenta ha sido creada correctamente"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   12&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   13&lt;/span&gt;         &lt;span style="color: blue;"&gt;return&lt;/span&gt; Authenticate(userName, password, &lt;span style="color: blue;"&gt;null&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   14&lt;/span&gt;     }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   15&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   16&lt;/span&gt;     TempData[&lt;span style="color: rgb(163, 21, 21);"&gt;"RegisterErrors"&lt;/span&gt;] = result.Errors;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   17&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   18&lt;/span&gt;     &lt;span style="color: blue;"&gt;return&lt;/span&gt; RedirectToAction(&lt;span style="color: rgb(163, 21, 21);"&gt;"Register"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   19&lt;/span&gt; }&lt;/p&gt;
&lt;/div&gt;
&lt;br /&gt;
Y ahora en las pruebas unitarias, comprobaremos que el método SendMessage se llama al crear un nuevo usuario. Utilizaremos &lt;strong&gt;&lt;a href="http://www.nunit.org"&gt;NUnit&lt;/a&gt;&lt;/strong&gt; como librería de pruebas y habrá que añadir la referencia al dll de Rhino Mocks de y de StructureMap al proyecto de pruebas.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background: white none repeat scroll 0% 0%; font-family: courier new; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    1&lt;/span&gt; [&lt;span style="color: rgb(43, 145, 175);"&gt;Test&lt;/span&gt;]&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    2&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; CreateUser_Creates_Users_And_Sends_Email()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    3&lt;/span&gt; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    4&lt;/span&gt;     &lt;span style="color: rgb(43, 145, 175);"&gt;MockRepository&lt;/span&gt; mocker = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;MockRepository&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    5&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    6&lt;/span&gt;     &lt;span style="color: rgb(43, 145, 175);"&gt;IMessagingService&lt;/span&gt; messagingService = mocker.StrictMock&lt;&lt;span style="color: rgb(43, 145, 175);"&gt;IMessagingService&lt;/span&gt;&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    7&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    8&lt;/span&gt;     &lt;span style="color: rgb(43, 145, 175);"&gt;Expect&lt;/span&gt;.Call(() =&gt; messagingService.SendMessage(&lt;span style="color: blue;"&gt;null&lt;/span&gt;, &lt;span style="color: blue;"&gt;null&lt;/span&gt;))&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    9&lt;/span&gt;         .IgnoreArguments();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   10&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   11&lt;/span&gt;     mocker.ReplayAll();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   12&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   13&lt;/span&gt;     &lt;span style="color: rgb(43, 145, 175);"&gt;ObjectFactory&lt;/span&gt;.Inject(messagingService);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   14&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   15&lt;/span&gt;     controller.CreateUser(&lt;span style="color: rgb(163, 21, 21);"&gt;"usuario"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"clave"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"direccion@correo.es"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   16&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   17&lt;/span&gt;     mocker.VerifyAll();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   18&lt;/span&gt; }&lt;/p&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Veamos con más detalle el código de esta prueba.&lt;br /&gt;
&lt;br /&gt;
En la línea 1 le indico a &lt;a title="Librería de pruebas unitarias" target="_blank" href="http://www.nunit.org"&gt;&lt;strong&gt;NUnit&lt;/strong&gt;&lt;/a&gt; que este método es una prueba.&lt;br /&gt;
&lt;br /&gt;
En la línea 4 creamos el objeto de Rhino Mocks que se encargará de generar los objectos Mocks a partir de la definición de la interfaz.&lt;br /&gt;
&lt;br /&gt;
En la línea 6 creamos obtenemos la implementación simulada del servicio IMessagingService. &lt;br /&gt;
&lt;br /&gt;
En la líneas 8 y 9, le decimos a Rhino Mocks que esperamos que en el futuro se llame al método SendMessage del objeto messagingService y que nos dan igual los argumentos utilizados. El método Expect.Call espera como parámetro un delegado que se lo hemos pasado utilizando una expressión lambda. &lt;br /&gt;
&lt;br /&gt;
En la línea 12, le indicamos al objeto MockRepository que ya hemos fijado todas las expectativas (en nuestro caso, sólo la establecida en la línea 8) y que vamos a empezar las pruebas.&lt;br /&gt;
&lt;br /&gt;
En la línea 13, inyectamos la interfaz simulada a &lt;strong&gt;StructureMap &lt;/strong&gt;para que utilice este objeto, en vez de lo que tenga en su configuración.&lt;br /&gt;
&lt;br /&gt;
En la línea 14, llamamos al objeto que estamos probando con algunos parámetros por defecto.&lt;br /&gt;
&lt;br /&gt;
En la línea 15, le pedimos a &lt;strong&gt;Rhino Mocks&lt;/strong&gt;, que verifique que se han cumplido todas las expectativas establecidas. En nuestro caso queríamos que se llamara al método SendMessage al crear un usuario. Si esto no ocurriera, este método lanzaría una excepción por lo que la prueba unitaria no se pasaría correctamente.&lt;br /&gt;
&lt;br /&gt;
¡Espero que te haya servido de ayuda!&lt;br /&gt;
</description>
      <link>http://www.avanzis.com/blogs/richard-chamorro/i/10414/837/utilizar-rhino-mocks-y-structuremap-en-pruebas-unitarias-con-nunit</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/richard-chamorro/i/10414/837/utilizar-rhino-mocks-y-structuremap-en-pruebas-unitarias-con-nunit</guid>
      <pubDate>Tue, 25 Nov 2008 16:01:37 GMT</pubDate>
    </item>
    <item>
      <title>Primeros pasos con StructureMap y la Inyección de Dependencias</title>
      <description>Uno de los objetivos que debe tener un buen programador es que su código esté poco acoplado, es decir, que dos componentes con funcionalidades distintas dependan el uno del otro lo mínimo posible. De esta forma conseguirá que sus dos componentes por separado sean reutilizables y más fáciles de mantener.&lt;br /&gt;
&lt;br /&gt;
Para eliminar al máximo la dependencia entre componentes, existe un patrón de diseño conocido como “&lt;strong&gt;Inyección de dependencias&lt;/strong&gt;” (“&lt;strong&gt;Dependency Injection&lt;/strong&gt;” o DI).  Este patrón consiste básicamente en que en vez de ser una clase la que crea objetos, estos se inyectan o resuelven en el último momento.&lt;br /&gt;
&lt;br /&gt;
Existen diferentes proyectos en .NET que intentan ayudarnos  a aplicar este patrón:&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;&lt;a href="http://www.castleproject.org/container/index.html" target="_blank"&gt; Castle Windsor Container&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;
    &lt;strong&gt;&lt;a href="http://structuremap.sourceforge.net" target="_blank" title="Dependency Injection con StructureMap"&gt;StructureMap&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd203104.aspx" target="_blank" title="Unity Application Block"&gt; Microsoft Unity Application Block&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
He decidido comenzar a utilizar StructureMap porque que es uno de los más extendidos y además me gusta su sintaxis y facilidad de uso.&lt;br /&gt;
&lt;br /&gt;
Para comenzar a utilizar la inyección de dependencias debes acostumbrarte a utilizar interfaces en vez de objetos concretos ya que esto es lo que te permitirá diferentes implementaciones de esa interfaz.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si queremos un componentes que realice el registro de errores o eventos, crearemos una interfaz “ILogger”. Y además, dos implementaciones de esta interfaz, una para guardar los mensajes en una base de datos y otra en un archivo de texto.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background: white none repeat scroll 0% 0%; font-family: courier new; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;interface&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ILogger&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: blue;"&gt;void&lt;/span&gt; Log(&lt;span style="color: blue;"&gt;string&lt;/span&gt; message);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;DatabaseLogger&lt;/span&gt; : &lt;span style="color: rgb(43, 145, 175);"&gt;ILogger&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Log(&lt;span style="color: blue;"&gt;string&lt;/span&gt; message)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: green;"&gt;// Lógica para guardar el mensaje en un archivo d texto..&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;p style="margin: 0px;"&gt; &lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;TextLogger&lt;/span&gt; :  &lt;span style="color: rgb(43, 145, 175);"&gt;ILogger&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Log(&lt;span style="color: blue;"&gt;string&lt;/span&gt; message)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: green;"&gt;// Lógica par aguardar el mensaje en un archivo de texto...&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;br /&gt;
Muy bien, ya tenemos dado el primer paso. Ahora añadiremos la referencia en nuestro proyecto a StructureMap.dll para poder utilizar esta librería.&lt;br /&gt;
&lt;br /&gt;
Cuando queramos utilizar el objeto ILogger dentro de otra clase, llamaremos método GetInstance() del objeto ObjectFactory que ofrece StructureMap.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background: white none repeat scroll 0% 0%; font-family: courier new; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ClaseDePrueba&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; HacerAlgo()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: green;"&gt;// ...&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: rgb(43, 145, 175);"&gt;ILogger&lt;/span&gt; logger = &lt;span style="color: rgb(43, 145, 175);"&gt;ObjectFactory&lt;/span&gt;.GetInstance&lt;&lt;span style="color: rgb(43, 145, 175);"&gt;ILogger&lt;/span&gt;&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        logger.Log(&lt;span style="color: rgb(163, 21, 21);"&gt;"Mensaje que queremos registrar"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        &lt;span style="color: green;"&gt;// ...&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;br /&gt;
Pero te preguntarás, ¿cómo sabe StructureMap cuál de las dos implementaciones de ILogger debe devolver, la de la base de datos o la del  archivo de texto? Obviamente eso hay que indicárselo de alguna forma. &lt;br /&gt;
&lt;br /&gt;
Podemos &lt;strong&gt;configurar StructureMap&lt;/strong&gt; o bien utilizando el archivo de configuración App.config o Web.config si es una aplicación web. O mediante código, normalmente al iniciarse el programa o en el archivo Global.asax si trabajas con ASP.NET.&lt;br /&gt;
&lt;br /&gt;
En este ejemplo, le indicaremos por código a StructureMap que queremos utilizar el archivo de texto para guardar los logs.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background: white none repeat scroll 0% 0%; font-family: courier new; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ConfigureStructureMap()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    &lt;span style="color: rgb(43, 145, 175);"&gt;ObjectFactory&lt;/span&gt;.Configure(&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;        s =&gt; s.BuildInstancesOf&lt;&lt;span style="color: rgb(43, 145, 175);"&gt;ILogger&lt;/span&gt;&gt;()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;            .TheDefaultIsConcreteType&lt;&lt;span style="color: rgb(43, 145, 175);"&gt;TextLogger&lt;/span&gt;&gt;()&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;    );&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;br /&gt;
¡Eso es todo! Ya estamos utilizando StructureMap y a partir de ahora, con cambiar una simple línea de código (o una línea del archivo de configuración si hubiéramos utilizado esa opción) podemos comenzar a utilizar la base de datos para guardar los mensajes en toda la aplicación.&lt;br /&gt;
&lt;br /&gt;
La &lt;strong&gt;Inyección de dependencias&lt;/strong&gt; es un patrón de diseño que todo programador debería conocer y utilizar. Además, esta técnica, unida al “&lt;strong&gt;Mocking&lt;/strong&gt;”, te será realmente útil si utilizas (¡deberías hacerlo!) &lt;strong&gt;pruebas unitarias&lt;/strong&gt;. Pero de esto ya hablaré en el futuro.&lt;br /&gt;
&lt;br /&gt;
¡Espero vuestros comentarios!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
</description>
      <link>http://www.avanzis.com/blogs/richard-chamorro/i/10401/837/primeros-pasos-con-structuremap-y-la-inyeccion-de-dependencias</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/richard-chamorro/i/10401/837/primeros-pasos-con-structuremap-y-la-inyeccion-de-dependencias</guid>
      <pubDate>Tue, 25 Nov 2008 13:26:48 GMT</pubDate>
    </item>
    <item>
      <title>El SEO y sus puntos clave.</title>
      <description>El SEO, o Search Engine Optimization, se refiere al conjunto de técnicas que debemos aplicar en una Web para que esté optimizada en buscadores y que salgamos bien posicionados.$0$0Técnicas SEO hay muchísimas, pero en mi opinión hay 6 que destacan sobre todas las demás:$0$0$0Tener &lt;span&gt;&lt;a href="http://www.sitemaps.org/"&gt;sitemaps&lt;/a&gt;&lt;/span&gt;.$0$0La palabra/frase clave debe ser el título de la página.$0$0La palabra/frase clave debe encontrarse dentro de la url de la página.$0$0La palabra/frase clave (debe estar dentro de un)/(debe ser el) H1 en la página.$0$0La palabra/frase clave debe estar repetida varias veces dentro de la página, algunas de ellas con negrita.$0$0Estructura de enlaces internos: todas las páginas de tu Web deben estar enlazadas entre ellas con pocos saltos de diferencia.$0$0Todo ello bajo la premisa de tener un buen contenido. Sin buen contenido no empezamos ni a hablar. Será este buen contenido el que te proporcione enlaces entrantes, y será la constancia el que haga que Google confíe en ti.$0$0Si estás interesado en técnicas SEO más avanzadas, te recomiendo el blog &lt;span&gt;&lt;a title="comunactivo" href="http://comunactivo.subgurim.net/"&gt;comunactivo&lt;/a&gt;&lt;/span&gt;.</description>
      <link>http://www.avanzis.com/blogs/xavi-navarro/i/10190/831/el-seo-y-sus-puntos-clave</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/xavi-navarro/i/10190/831/el-seo-y-sus-puntos-clave</guid>
      <pubDate>Wed, 19 Nov 2008 13:38:35 GMT</pubDate>
    </item>
    <item>
      <title>Jugando con jQuery: emulando el FindControl de ASP.NET</title>
      <description>Esto de &lt;strong&gt;jQuery&lt;/strong&gt; es divertido. Igual de divertido que &lt;strong&gt;javascript &lt;/strong&gt;pero más fácil.&lt;br /&gt;
&lt;br /&gt;
Hace unos días di una primero &lt;strong&gt;&lt;a href="http://www.avanzis.com/blogs/xavi-navarro/i/9120/831/introduccion-a-jquery"&gt;introducción a jQuery&lt;/a&gt;&lt;/strong&gt; e hice mi &lt;a href="http://www.avanzis.com/blogs/xavi-navarro/i/9123/831/jugando-con-jquery-macemulator"&gt;primer plugin&lt;/a&gt; que llamé macEmulator.&lt;br /&gt;
&lt;br /&gt;
Ahora presento un nuevo plugin que responde a una necesidad real y casi diaria de todo programador en ASP.NET (a no ser que trabaje con &lt;a href="http://www.avanzis.com/blogs/richard-chamorro/i/8677/837/asp-net-mvc-preview-5"&gt;MVC&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
Se trata de emular el FindControl de ASP.NET pero con javascript. Vayamos a un ejemplo:&lt;br /&gt;
&lt;br /&gt;
Tenemos un DataList con un ItemTemplate que tiene dos Panels y un Label en cada Panel&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;asp:DataList ID="DataList1" runat="server"&gt;&lt;br /&gt;
    &lt;ItemTemplate&gt;&lt;br /&gt;
        &lt;asp:Panel ID="Panel1" runat="server"&gt;&lt;br /&gt;
            &lt;asp:Label ID="Label1" runat="server" Text="Label1"&gt;&lt;/asp:Label&gt;&lt;br /&gt;
        &lt;/asp:Panel&gt;&lt;br /&gt;
        &lt;asp:Panel ID="Panel2" runat="server"&gt;&lt;br /&gt;
            &lt;asp:Label ID="Label2" runat="server" Text="Label2"&gt;&lt;/asp:Label&gt;&lt;br /&gt;
        &lt;/asp:Panel&gt;&lt;br /&gt;
    &lt;/ItemTemplate&gt;&lt;br /&gt;
&lt;/asp:DataList&gt;&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
Esto generará un código HTML que convertirá las Label en elementos &lt;span /&gt; con un identificador de este estilo: &lt;em&gt;DataList1_ctl00_Label1&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
Pero yo lo que quiero es acceder a las Label1 por jQuery... ¿cómo lo hago?&lt;br /&gt;
&lt;br /&gt;
No hay una forma directa porque los IDs los genera ASP.NET, pero con el plugin que presento podremos hacer algo como esto:&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;var controls = $(document).findControl('Label1');&lt;br /&gt;
for (i = 0; i &lt; controls.length; i++) { alert(controls[i].innerHTML); }&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
El plugin no es que sea una obra de arte. Más bien es sencillito, jeje. Lo autoexplican los comentarios:&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;jQuery.fn.findControl = function(clientId) {&lt;br /&gt;
    var ids = new Array();&lt;br /&gt;
    &lt;br /&gt;
    // Para cada elemento que tenga un atributo ID dentro de "this"&lt;br /&gt;
    $(this).find('*[id]').each(function(i) {&lt;br /&gt;
        // Si el ID del elemento termina como el clientId, lo añadimos al array&lt;br /&gt;
        if (this.id &amp;&amp;&lt;br /&gt;
            (this.id.lastIndexOf(clientId) &gt;= 0) &amp;&amp; &lt;br /&gt;
            (this.id.lastIndexOf(clientId) == (this.id.length - clientId.length))) {&lt;br /&gt;
                ids.push(this);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
        &lt;br /&gt;
    // Devolvemos el array&lt;br /&gt;
    return ids;&lt;br /&gt;
}&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
El plugin ya viene con bugs por defecto, como el hecho de que si otro elemento se llamara MyLabel1, el plugin se creería que es Label1... pero bueno, es una primera aproximación.&lt;br /&gt;
&lt;br /&gt;
</description>
      <link>http://www.avanzis.com/blogs/xavi-navarro/i/9162/831/jugando-con-jquery-emulando-el-findcontrol-de-asp-net</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/xavi-navarro/i/9162/831/jugando-con-jquery-emulando-el-findcontrol-de-asp-net</guid>
      <pubDate>Sun, 05 Oct 2008 10:54:49 GMT</pubDate>
    </item>
    <item>
      <title>Jugando con jQuery: macEmulator</title>
      <description>Tras la breve &lt;strong&gt;&lt;a href="http://www.avanzis.com/blogs/xavi-navarro/i/9120/831/introduccion-a-jquery"&gt;introducción a jQuery&lt;/a&gt;&lt;/strong&gt;, propongo un ejemplo que he llamado "macEmulator". La verdad es que soy bastante malo dando nombre a las cosas, y en el mundo de la programación tenemos que estar todo el santo día dando nombres a variables, a funciones, a clases, a ficheros...&lt;br /&gt;
&lt;br /&gt;
El "macEmulator" lo que hace es coger las imágenes ubicadas dentro del "div" que le indiquemos y darles un efecto similar al de los iconos de los Mac. Cuando el ratón está encima de un icono la imagen se hace grande (progresivamente) y cuando sales se hace pequeña (también de forma progresiva).&lt;br /&gt;
&lt;br /&gt;
Lo he puesto dentro de un plugin, de forma que activar la funcionalidad se reduce a una sola línea de código:&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;strong&gt;$("#divId").macEmulation(100,150,100,500);&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
Donde:&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;divId es el "id" del div en el que están ubicadas las imágenes.&lt;/li&gt;
    &lt;li&gt;El primer parámetro marca la anchura inicial de las imágenes&lt;/li&gt;
    &lt;li&gt;El segundo parámetro marca la anchura de la imagen cuando el ratón está sobre ella.&lt;/li&gt;
    &lt;li&gt;El tercer parámetro marca la anchura de la imagen cuando el ratón deja de estar sobre ella.&lt;/li&gt;
    &lt;li&gt;El cuarto parámetro marca el tiempo que tarda la imagen en transformarse progresivamente de grande a pequeña y de pequeña a grande.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
A continuación muestro el código con comentarios para entender el script:&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;jQuery.fn.macEmulation = function(initialWitdh, hoverWidth, houtWidth, delay) {&lt;br /&gt;
    // Cogemos el elemento dentro del cual estarán las imágenes&lt;br /&gt;
    var div = $(this);&lt;br /&gt;
&lt;br /&gt;
    // Cuando la página esté cargada, aplicaremos la anchura inicial marcada&lt;br /&gt;
    // y pondremos cada imagen dentro de un div con unos estilos predefinidos&lt;br /&gt;
    $(document).ready(function() {&lt;br /&gt;
        div.find('img').width(initialWitdh);&lt;br /&gt;
        div.find('img').wrap('&lt;div style="float:left; padding-right:5px;"&gt;&lt;/div&gt;');&lt;br /&gt;
&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // Asignamos la anchura de la imagen cuando estamos sobre ella y cuando dejamos de estarlo.&lt;br /&gt;
    // Para ello utilizaremos el modo "animate" que hará que la transición sea progresiva.&lt;br /&gt;
    div.find('img').hover(&lt;br /&gt;
    function() {&lt;br /&gt;
        $(this).animate({ width: hoverWidth + "px" }, delay);&lt;br /&gt;
    },&lt;br /&gt;
    function() {&lt;br /&gt;
        $(this).animate({ width: houtWidth + "px" }, delay);&lt;br /&gt;
    });&lt;br /&gt;
}&lt;/em&gt;
</description>
      <link>http://www.avanzis.com/blogs/xavi-navarro/i/9123/831/jugando-con-jquery-macemulator</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/xavi-navarro/i/9123/831/jugando-con-jquery-macemulator</guid>
      <pubDate>Thu, 02 Oct 2008 13:46:17 GMT</pubDate>
    </item>
    <item>
      <title>Introducción a jQuery</title>
      <description>&lt;strong&gt;Javascript &lt;/strong&gt;ha sido siempre un eterno candidato a desaparecer. Sin embargo, con el paso de los años su importancia en el mundo Web ha ido en aumento.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Javascript &lt;/strong&gt;no suele gustar. Se puede hacer muchísimas cosas con él, pero tiene varios inconvenientes. Empezando por la selectiva incompatibilidad entre navegadores, y acabando por una curva de aprendizaje no lineal (hacer cosas fáciles es fácil, hacer cosas difíciles es muy difícil... y en el medio hay poquito).&lt;br /&gt;
&lt;br /&gt;
Para los que hemos trabajado con javascript desde sus inicios, solemos tener pequeñas librerías que nos hacen todo lo que queremos. Pero suelen ser librerías poco estándar... vamos, que cada uno las tiene de su padre y de su madre.&lt;br /&gt;
&lt;br /&gt;
Es por eso que últimamente en la oficina suena mucho "&lt;strong&gt;&lt;a href="http://www.avanzis.com/blogs/richard-chamorro/i/9010/837/jquery-en-visual-studio-algo-esta-cambiando-en-microsoft"&gt;jQuery&lt;/a&gt;&lt;/strong&gt;", del que &lt;a href="http://www.avanzis.com/blogs/richard-chamorro"&gt;Richard&lt;/a&gt; ya ha hablado. Básicamente, &lt;strong&gt;jQuery&lt;/strong&gt; es un framework javascript, que nos permite olvidarnos de las incompatibilidades y linealiza mucho la curva de aprendizaje. El framework propone un estándar de trabajo con &lt;strong&gt;javascript&lt;/strong&gt;, que no sólo lo hace más fácil sino que le añade funcionalidades extremadamente útiles en pocas líneas de código.&lt;br /&gt;
&lt;br /&gt;
Para más regocijo, su &lt;a href="http://jquery.com/"&gt;Web oficial&lt;/a&gt; es muy útil, clara y llena de ejemplos, con buenos &lt;a href="http://docs.jquery.com/Tutorials"&gt;tutoriales&lt;/a&gt; y &lt;a href="http://plugins.jquery.com/"&gt;muchos plugins&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
En próximos artículos pondré ejemplos de algunas de las cosas que se puede hacer con jQuery. Serán ejemplo específicos, porque la &lt;a href="http://jquery.com/"&gt;Web oficial de jQuery&lt;/a&gt; ya es muy clara.&lt;br /&gt;
</description>
      <link>http://www.avanzis.com/blogs/xavi-navarro/i/9120/831/introduccion-a-jquery</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/xavi-navarro/i/9120/831/introduccion-a-jquery</guid>
      <pubDate>Thu, 02 Oct 2008 13:30:44 GMT</pubDate>
    </item>
    <item>
      <title>jQuery en Visual Studio. Algo está cambiando en Microsoft</title>
      <description>&lt;p&gt;Cuando hoy he leído el último artículo de Scott Guthrie - Scottgu para los amigos –‘&lt;strong&gt;&lt;a title="jQuery and Microsoft" target="_blank" href="http://weblogs.asp.net/scottgu/archive/2008/09/28/jquery-and-microsoft.aspx"&gt;jQuery and Microsoft&lt;/a&gt;&lt;/strong&gt;’, me he quedado alucinado. &lt;/p&gt;
&lt;p&gt;La noticia en sí es muy buena: van a comenzar a distribuir jQuery, mi librería Javascript favorita, junto con Visual Studio. No sólo eso. Además darán soporte nativo de ‘Intellisense’ en su editor, crearán controles para AJAX Control Toolkit, la integrarán con ASP.NET MVC y contribuirán con pruebas, corrección de errores y parches.&lt;/p&gt;
&lt;p&gt;Nosotros ya estamos usando jQuery en nuestros nuevos proyectos, y los diseñadores de Avanzis ya han comenzado a utilizarlo cuando necesitan realizar efectos avanzados con Javascript.&lt;/p&gt;
&lt;p&gt;Las &lt;strong&gt;principales ventajas de jQuery&lt;/strong&gt; son:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;No es intrusivo.&lt;/strong&gt;&lt;br /&gt;
    Esto significa que no se mezcla el código HTML con Javascript, con lo que se consigue un código más limpio y fácil de mantener.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Simplifica las tareas habituales de Javascript.&lt;/strong&gt;&lt;br /&gt;
    Seleccionar un elemento DOM, añadir una clase, ejecutar una función para cada elemento, crear una animación… Todo esto y mucho más es más sencillo con jQuery.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Es independiente del navegador. &lt;/strong&gt;&lt;br /&gt;
    No tienes que escribir código distinto para Firefox, Internet Explorer, Google Chrome, Opera, etc.… &lt;span&gt; &lt;/span&gt;jQuery lo hace transparente para el desarrollador.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Ocupa muy poco&lt;/strong&gt;. &lt;br /&gt;
    ¡La librería comprimida apenas llega&lt;span&gt;  &lt;/span&gt;las 15KB!&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Extensible. &lt;/strong&gt;&lt;br /&gt;
    Dispones de cientos de &lt;a href="http://plugins.jquery.com/" title="jQuery Plugins"&gt;&lt;strong&gt;extensiones para jQuery&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt; que puedes utilizar y también están comenzado a implementar de forma oficial controles gráficos con ‘&lt;a href="http://ui.jquery.com/" title="jQuery UI"&gt;&lt;strong&gt;jQuery UI&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;’.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si no conoces jQuery… ¡es el momento para aprender! Puedes encontrar &lt;a title="Tutoriales jQuery" target="_blank" href="http://docs.jquery.com/Tutorials"&gt;&lt;strong&gt;tutoriales sobre jQuery&lt;/strong&gt;&lt;/a&gt; en su página oficial y espero que &lt;a title="Eva Guillem" href="http://www.avanzis.com/blogs/eva-guillem"&gt;Eva&lt;/a&gt; escriba algún artículo en su blog ya que es una experta y ha estado últimamente comparándolo con otras librerías javascript como &lt;a title="Librería Javascript Prototype" target="_blank" href="http://www.prototypejs.org/"&gt;&lt;strong&gt;Prototype&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pero la noticia subyacente es más importante. Se ha producido definitivamente un gran cambio de filosofía en Microsoft respecto a los proyectos “Open Source”. Por primera vez - que yo conozca - la gente de Microsoft NO va a duplicar la funcionalidad de un proyecto de código abierto, si no que lo va a adoptar para su causa y va a contribuir a mejorarlo.&lt;/p&gt;
&lt;p&gt;Hasta el momento, muchos de los proyectos de código abierto de mayor éxito han tenido su versión particular de Microsoft. Algunos ejemplos que me vienen ahora a la memoria:&lt;/p&gt;
&lt;table width="100%" cellspacing="4" cellpadding="0" border="0"&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;Proyecto de código abierto&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong&gt;Solución de Microsoft&lt;/strong&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;a title="NUnit" target="_blank" href="http://www.nunit.org"&gt;NUnit&lt;/a&gt;, &lt;a title="MBUnit" href="http://www.mbunit.com/"&gt;MBUnit&lt;/a&gt;&lt;/td&gt;
            &lt;td&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting%28VS.80%29.aspx"&gt;Microsoft.VisualStudio.TestTools.UnitTesting&lt;/a&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;a title="MonoRail MVC Framework" href="http://www.castleproject.org/MonoRail/"&gt;MonoRail&lt;/a&gt;&lt;/td&gt;
            &lt;td&gt;&lt;a href="http://www.asp.net/mvc/"&gt;ASP.NET MVC&lt;/a&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;a title="StructureMap" href="http://structuremap.sourceforge.net/Default.htm"&gt;StructureMap&lt;/a&gt;, &lt;a href="http://www.castleproject.org/container/index.html"&gt;MicroKernel&lt;/a&gt;&lt;/td&gt;
            &lt;td&gt;&lt;a title="Unity Application Block" href="http://msdn.microsoft.com/en-us/library/cc468366.aspx"&gt;Unity&lt;/a&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;a href="http://nant.sourceforge.net/"&gt;NAnt&lt;/a&gt; &lt;/td&gt;
            &lt;td&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/wea2sca5.aspx"&gt;MSBuild&lt;/a&gt; &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Y un largo etcétera.&lt;/p&gt;
&lt;p&gt;No sé si es un cambio en la visión de sus directivos, por la presión de la competencia como Google, o por la insistencia de sus desarrolladores principales pero, definitivamente, algo está cambiando en Microsoft.&lt;/p&gt;
&lt;p&gt;Editado: José M. Aguilar de &lt;a href="http://www.variablenotfound.com/2008/09/jquery-microsoft-y-t.html" title="variablenotfound.com"&gt;www.variablenotfound.com&lt;/a&gt; ya hace referencia a esta noticia.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
</description>
      <link>http://www.avanzis.com/blogs/richard-chamorro/i/9010/837/jquery-en-visual-studio-algo-esta-cambiando-en-microsoft</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/richard-chamorro/i/9010/837/jquery-en-visual-studio-algo-esta-cambiando-en-microsoft</guid>
      <pubDate>Sun, 28 Sep 2008 13:54:07 GMT</pubDate>
    </item>
    <item>
      <title>De vuelta a la oficina tras las vacaciones</title>
      <description>Primer día de trabajo en &lt;strong&gt;Avanzis&lt;/strong&gt; tras algo más de tres semanas de merecidas vacaciones, las cuales me han servido no solo para desconectar literalmente de &lt;strong&gt;Internet&lt;/strong&gt;, lo cual ya es todo un logro para alguien que está constantemente pendiente de un &lt;strong&gt;ordenador&lt;/strong&gt;, sino que además he podido disfrutar de una mini escapada a &lt;strong&gt;Vitoria&lt;/strong&gt;, ciudad realmente preciosa para aquellos que sepan ver en las ciudades algo más que hileras de pisos en los que vivir.&lt;br /&gt;
&lt;br /&gt;
Para los que trabajamos constantemente con &lt;strong&gt;ordenadores&lt;/strong&gt;, resulta de vital importancia poder tener unos días de relajación total, manteniendo nuestras manos lejos del teclado y del ratón, para por lo menos sentir esa sensación de no dependencia hacia una maquina. Pero hay que reconocer que, incluso estando de vacaciones, no resulta nada fácil levantarse por la mañana y evitar levantar la tapa del &lt;strong&gt;portátil&lt;/strong&gt;, aunque sólo sea para conocer las &lt;strong&gt;noticias&lt;/strong&gt; de última hora.&lt;br /&gt;
&lt;br /&gt;
Lo mejor de todo, la sensación de haber podido descansar, de haber disfrutado del &lt;strong&gt;tiempo libre&lt;/strong&gt; para hacer esas cosas que normalmente la &lt;strong&gt;rutina&lt;/strong&gt; de cada día nos priva de realizar. El resultado, la &lt;strong&gt;vuelta al trabajo&lt;/strong&gt; se torna mucho más fácil cuando uno tiene la sensación de haber aprovechado bien sus &lt;strong&gt;vacaciones&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
Mi consejo, sobre todo para los que trabajamos en el sector de las &lt;strong&gt;nuevas tecnologías&lt;/strong&gt;, en vacaciones desconectar por unos días totalmente del mundo de las máquinas, desenchufar los &lt;strong&gt;móviles&lt;/strong&gt;, dejar el &lt;strong&gt;ordenador&lt;/strong&gt; apagado, y si os cuesta, es tan fácil como esconder el &lt;strong&gt;router&lt;/strong&gt; en algún remoto rincón, al menos por unos días. Relamente merece la pena...
</description>
      <link>http://www.avanzis.com/blogs/javier-belmonte/i/8843/805/de-vuelta-a-la-oficina-tras-las-vacaciones</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/javier-belmonte/i/8843/805/de-vuelta-a-la-oficina-tras-las-vacaciones</guid>
      <pubDate>Sun, 14 Sep 2008 10:18:39 GMT</pubDate>
    </item>
    <item>
      <title>Google Chrome - El nuevo navegador web de Google</title>
      <description>&lt;span class="Apple-style-span" style="border-collapse: separate; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-family: 'times new roman'; font-size: 16px; color: rgb(0, 0, 0);"&gt;
&lt;div style="margin: 0px; padding: 3px; background-image: none; text-align: left; font-family: verdana,tahoma,arial,helvetica; font-size: 11px;"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Desde hace unos minutos está disponible&lt;span class="Apple-converted-space"&gt; &lt;/span&gt;&lt;strong&gt;Google Chrome&lt;/strong&gt;, el navegador web creado por Google.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Lo puedes descargar en este enlace:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;strong&gt;&lt;a href="http://www.google.es/chrome" target="_blank" title="Google Chrome, el navegador Internet de Google"&gt;http://www.google.es/chrome&lt;/a&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Y en estos momentos tengo sensaciones encontradas:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Desde el punto de vista de usuario estoy encantado. Google Chrome parece sencillo de usar, rápido y tiene algunas funcionalidades muy interesantes. Promete ocupar poca memoria y ser veloz como ningún otro navegador a la hora de ejecutar javascript. ¡La descarga ocupa menos de 500KB!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Desde el punto de vista de desarrollador web, esto es una faena. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Con dos navegadores mayoritarios - Internet Explorer y Firefox - con sus versiones - Internet Explorer 4.0, 5.0, 6.0, 7.0 y en breve Internet Explorer 8 y Firefox 1.0, 2.0 y 3.0 - ya teníamos más que suficiente, ya que cada web y aplicación que desarrollamos es necesario probarla al menos en los navegadores principales y con sus versiones más usadas.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;En un mundo ideal, el desarrollo web tendría que realizarse como si únicamente existiera una navegador y este interpretara a la perfección los estándares, pero en la realidad no todos los navegadores se comportan igual a la hora de mostrar una página, ni tienen las mismas funcionalidades javascript. Si Google Chrome tiene éxito y es adoptado por muchos usuarios, nuestro esfuerzo como desarrolladores web se multiplicará inevitablemente.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Por suerte, mis primeras pruebas con Google Chrome son esperanzadoras tras probar algunas de nuestras webs: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="http://www.todoexpertos.com/" target="_blank" title="Todoexpertos.com - Expertos reales responde a tus preguntas"&gt;Todoexpertos.com&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="http://www.euroleague.net/" target="_blank" title="Euroleague Basketball"&gt;Euroleague.net&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="http://www.bookingpark.com/" target="_blank" title="Reserva de entradas en parques de atracciones"&gt;Bookingpark.com&lt;/a&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;¡Todas ellas se han mostrado perfectamente!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;También he accedido a la parte de administración&lt;span class="Apple-converted-space"&gt; &lt;/span&gt;&lt;a href="../../productos/informacion/webportal" target="_blank" title="Webportal - Gestor avanzado de contenidos web"&gt;&lt;strong&gt;Webportal&lt;/strong&gt;&lt;/a&gt;, nuestro gestor de contenidos y... ¡ningún problema aparente! &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Lástima que el&lt;span class="Apple-converted-space"&gt; &lt;/span&gt;&lt;a href="../../nosotros/zona-de-prensa/i/8135/207/nuevo-editor-html-para-webportal" target="_self" title="Editor HTML"&gt;&lt;strong&gt;editor HTML&lt;/strong&gt;&lt;/a&gt;&lt;span class="Apple-converted-space"&gt; &lt;/span&gt;online que utilizamos y que hace un uso extensivo de javascript, ajax y comportamiento del servidor, no se ha comportado del todo bien. Por supuesto, ya estamos investigando cómo solucionarlo.&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Google Chrome, tiene muy buena pinta. Así que quizá los desarrolladores web hayamos asistido hoy a un antes y un después en Internet.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/span&gt;
</description>
      <link>http://www.avanzis.com/blogs/richard-chamorro/i/8707/837/google-chrome-el-nuevo-navegador-web-de-google</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/richard-chamorro/i/8707/837/google-chrome-el-nuevo-navegador-web-de-google</guid>
      <pubDate>Mon, 01 Sep 2008 21:02:50 GMT</pubDate>
    </item>
    <item>
      <title>ASP.NET MVC Preview 5</title>
      <description>!Acaban de lanzar la&lt;a title="ASP.NET MVC Preview 5" href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx"&gt; preview 5 de ASP.NET MVC&lt;/a&gt; en Codeplex!&lt;br /&gt;
&lt;br /&gt;
Si eres de los valientes (como nosotros) que estas desarrollando con ASP.NET MVC, recuerda que tendrás que desinstalar la versión anterior antes de instalar este nuevo lanzamiento.&lt;br /&gt;
&lt;br /&gt;
Por si nos os apetece leer, y ya que tengo que revisar los cambios en profundidad, aquí tenéis  algunas de las nuevas características respecto a la Preview 4:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Mejoras en los motores de visualización (ViewEngine)&lt;/strong&gt;&lt;br /&gt;
    &lt;ul&gt;
        &lt;li&gt;Ahora, en vez de ser cada controlador el responsable de decidir que motor de visualización se utilizará, los motores se registran de forma global.&lt;/li&gt;
        &lt;li&gt;Se ha modificado la interfaz IViewEngine para que añada el método "RenderPartial".&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Mejoras en los helpers&lt;/strong&gt;
    &lt;ul&gt;
        &lt;li&gt;Soporte para la renderización de views parciales.&lt;/li&gt;
        &lt;li&gt;Nuevo parámetro para poder indicar a un DropDownList cuál será su opción por defecto.&lt;/li&gt;
        &lt;li&gt;Se han movido las extensiones AJAX a otro namespace, teóricamente para que sea más sencillo reemplazarlas por tu propio código.&lt;/li&gt;
        &lt;li&gt;Otras mejoras&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Mejoras en los controles y los filtros.&lt;/strong&gt;
    &lt;ul&gt;
        &lt;li&gt;Los parámetros de las acciones ahora soportan también arrays. &lt;br /&gt;
        Esto ocurría cuando varios controles tienen el mismo nombre.&lt;/li&gt;
        &lt;li&gt;Soporte a para crear tus propios "binders". Los binders asocian los valores que llegan por querystring o form con parámetros de la acción.&lt;/li&gt;
        &lt;li&gt;Añadida la interfaz "IActionInvoker" para desacoplar el controlador la implementación específica de "ControllerActionInvoker".&lt;/li&gt;
        &lt;li&gt;Añadido el modo actualización (UpdateMode) a la clase del controlador. Es posible utilizar este método para actualizar las propiedades de un modelo a partir de los parámetros pasados en el formulario.&lt;/li&gt;
        &lt;li&gt;Se ha modificado "HandleErrorAttribute" para que mientras estás desarrollando aparezca la ventana amarilla de error que proporciona la máxima información posible.&lt;/li&gt;
        &lt;li&gt;Nuevo atributo "AcceptVerbs". Permite indicar qué verbos HTTP son aceptados (GET, POST, etc...). Esto permite tener dos acciones con el mismo nombre siempre y cuando acepten verbos diferentes.&lt;/li&gt;
        &lt;li&gt;Nuevo atributo "ActionName". Permite indicar un nombre de acción a un método diferente del nombre del método. Su ejemplo para estas dos últimas mejoras es bastante claro:&lt;br /&gt;
        &lt;br /&gt;
        [AcceptVerb("GET")]&lt;br /&gt;
        public ActionResult MyAction(...);&lt;br /&gt;
        &lt;br /&gt;
        [ActionName("MyAction"), AcceptVerb("POST")]&lt;br /&gt;
        public ActionResult MyAction_FormSubmit(...);&lt;br /&gt;
        &lt;br /&gt;
        [AcceptVerb("GET")]&lt;br /&gt;
        public ActionResult OtherActionOverloaded(string id);&lt;br /&gt;
        &lt;br /&gt;
        [AcceptVerb("POST")]&lt;br /&gt;
        public ActionResult OtherActionOverloaded(string id, ...);&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Muy bonita toda esta explicación, pero ¿cómo nos ha afectado a nostros en &lt;a title="Proyecto ASP.NET MVC" href="http://www.avanzis.com/blogs/josep-planells/i/8292/834/scrum-test-driven-development-y-mvc-vamos-a-ser-agiles"&gt;el proyecto que estamos realizando en ASP.NET MVC&lt;/a&gt;?&lt;br /&gt;
&lt;br /&gt;
Estos son los problemas que hemos encontrado para que nuestro proyecto compile tras haber actualizado a la preview 5:&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;El objeto "LinkBuilder" ahora se encuentra en el espacio de nombre "Microsoft.Web.Mvc". Este objeto lo utilizamos para generar un "RouteValueDictionary" a partir de una expresión de Linq. &lt;/li&gt;
    &lt;li&gt;El método ActionLink&lt;T&gt; que adminte como tipo un controlador, se ha movido también a Microsoft.Web.Mvc.&lt;/li&gt;
    &lt;li&gt;BindingHelperExtensions ya no existe y aún no he encontrado ningún objeto equivalente.&lt;/li&gt;
    &lt;li&gt;El controlador ya no tiene la propiedad ViewEngine.ç&lt;/li&gt;
    &lt;li&gt;Html.RenderUserControl() ya no existe, ahora hay que usar Html.RenderPartial(). Por ejemplo:&lt;br /&gt;
     &lt;%=Html.RenderUserControl("~/UserControls/TagList.ascx", ViewData.Model.PopularTags)%&gt;&lt;br /&gt;
    Ahora será:&lt;br /&gt;
     &lt;% Html.RenderPartial("~/UserControls/TagList.ascx", ViewData.Model.PopularTags);%&gt;&lt;br /&gt;
    Fíjate que ahora no hay que poner el igual delante, y que tiene que acabar con punto y coma. &lt;/li&gt;
&lt;/ul&gt;
¿Alguien más se está peleando con ASP.NET MVC? Me encantaría escuchar vuestros comentarios.  &lt;br /&gt;
&lt;br /&gt;
</description>
      <link>http://www.avanzis.com/blogs/richard-chamorro/i/8677/837/asp-net-mvc-preview-5</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/richard-chamorro/i/8677/837/asp-net-mvc-preview-5</guid>
      <pubDate>Thu, 28 Aug 2008 17:14:20 GMT</pubDate>
    </item>
    <item>
      <title>Trucos FLASH: Obtención de variables desde QueryString</title>
      <description>Cada día, en el transcurrir de una &lt;strong&gt;empresa&lt;/strong&gt; dedicada al &lt;strong&gt;desarrollo web&lt;/strong&gt;, ya sea incluso en un mes de agosto, surgen a menudo nuevas especificaciones o requerimientos que nos obligan a investigar soluciones que quizás antes jamás habíamos utilizado. Además esto ocurre frecuentemente cuando se trata de &lt;strong&gt;proyectos web&lt;/strong&gt; que incorporan animaciones en &lt;strong&gt;flash&lt;/strong&gt;, donde en ocasiones la integración e interacción de dicho archivo con nuestro &lt;strong&gt;gestor de contenidos&lt;/strong&gt; requiere del ingenio, da la experiencia, pero sobre todo de la capacidad que &lt;strong&gt;actionscript&lt;/strong&gt; nos ofrece.&lt;br /&gt;
&lt;br /&gt;
Ayer mismo se nos planteó la necesidad de modificar el valor de una variable utilizada en un archivo &lt;strong&gt;flash&lt;/strong&gt; en función del valor de un parámetro del &lt;strong&gt;QueryString&lt;/strong&gt; de una &lt;strong&gt;URL&lt;/strong&gt;. Algo que, tras un par de horas de analisis y de investigación, resulta realmente sencillo de realizar, pero que dicho así de buenas a primeras parece más complejo de lo que es. Aprovecharé además para explicar como de forma sencilla podemos cambiar ciertos aspectos de un mismo fichero &lt;strong&gt;flash&lt;/strong&gt;, solamente mediante el paso directo de parámetros sobre la definición del &lt;strong&gt;object&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;PASO DE PARÁMETROS DIRECTAMENTE SOBRE EL FLASH&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
En algunas ocasiones puede interesarnos, sin mayores complicaciones, que un mismo &lt;strong&gt;flash&lt;/strong&gt; se comporte de forma diferente, cambie su color de fondo, o incluso que tenga una apariencia diferente, solamente con cambiar el valor de una de sus variables. Esto, que en apariencia resulta tan absurdo, puede ayudarnos a reutilizar un mismo fichero &lt;strong&gt;flash&lt;/strong&gt;, en varias circunstancias diferentes. Sobre todo es muy útil para ajustar por ejemplo el &lt;strong&gt;&lt;em&gt;look and feel&lt;/em&gt;&lt;/strong&gt; de un mismo fichero flash al diseño de distintos &lt;strong&gt;portales web&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;Ejemplo 1.1:&lt;/strong&gt;&lt;/span&gt; Nuestro fichero &lt;strong&gt;flash&lt;/strong&gt; sustenta su fondo en una fichero de imagen que nosotros podemos cambiar a nuestro antojo. Para ello mediante la simple asignación de una &lt;strong&gt;url relativa&lt;/strong&gt; a la variable &lt;strong&gt;&lt;em&gt;imageFileName&lt;/em&gt;&lt;/strong&gt; podremos cambiar dicha imagen de fondo.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;object width="250" height="150" id="flaMovie" &lt;br /&gt;
codebase="http://macromedia.com/cabs/swflash.cab#version=4,0,0,0" &lt;br /&gt;
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"&gt;&lt;br /&gt;
    &lt;param name="movie" value="flaMovie.swf"&gt;&lt;br /&gt;
&lt;/em&gt;&lt;strong&gt;&lt;em&gt;    &lt;param name="imageFileName" value="imagen01.jpg"&gt;&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;em&gt;    &lt;embed src="flaMovie.swf" bgcolor="#99CC33" &lt;br /&gt;
    type="application/x-shockwave-flash height="150" width="250"&gt;&lt;br /&gt;
&lt;/object&gt;&lt;br /&gt;
&lt;/em&gt;&lt;br /&gt;
&lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;Ejemplo 1.2:&lt;/strong&gt;&lt;/span&gt; Con la misma intención que en el anterior ejemplo, esta vez la variable la definimos directamente sobre la propia &lt;strong&gt;url relativa&lt;/strong&gt; de la película &lt;strong&gt;flash&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;object width="250" height="150" id="flaMovie" &lt;br /&gt;
codebase="http://macromedia.com/cabs/swflash.cab#version=4,0,0,0" &lt;br /&gt;
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"&gt;&lt;br /&gt;
&lt;strong&gt;    &lt;param name="movie" &lt;br /&gt;
    value="flaMovie.swf?imageFilename=imagen01.jpg"&gt;&lt;/strong&gt;&lt;br /&gt;
    &lt;embed &lt;strong&gt;src="flaMovie.swf?imageFilename=imagen01.jpg"&lt;/strong&gt; &lt;br /&gt;
    bgcolor="#99CC33" type="application/x-shockwave-flash &lt;br /&gt;
    height="150" width="250"&gt;&lt;br /&gt;
&lt;/object&gt;&lt;br /&gt;
&lt;/em&gt;&lt;br /&gt;
&lt;strong&gt;PASO DE PARÁMETROS POR QUERYSTRING&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
En nuestro caso en particular lo que necesitábamos es que este paso de variables se hiciera directamente desde el &lt;strong&gt;QueryString&lt;/strong&gt; de una &lt;strong&gt;url&lt;/strong&gt;. Además por cuestiones de optimización optamos porque de todas los posibles variables que puedan encontrarse en el &lt;strong&gt;QueryString&lt;/strong&gt;, tan sólo queremos tener en cuenta la variable definida como &lt;strong&gt;&lt;em&gt;tipo&lt;/em&gt;&lt;/strong&gt;, algo que podremos también controlar mediante &lt;strong&gt;actionscript&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;Ejemplo 2:&lt;/strong&gt;&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;import flash.external.*; //para poder usar externalInterface&lt;br /&gt;
&lt;br /&gt;
var paramTipo;&lt;br /&gt;
var queryString = ExternalInterface.call("window.location.search.substring", 1);&lt;br /&gt;
&lt;br /&gt;
if(queryString) {&lt;br /&gt;
    var allParams:Array = queryString.split('&amp;');&lt;br /&gt;
&lt;br /&gt;
    for (var i = 0, index = -1; i &lt; allParams.length; i++) {&lt;br /&gt;
        var keyValuePair:String = allParams[i];&lt;br /&gt;
&lt;br /&gt;
        if((index = keyValuePair.indexOf("=")) &gt; 0) {&lt;br /&gt;
            var paramKey:String = keyValuePair.substring(0,index);&lt;br /&gt;
            var paramValue:String = keyValuePair.substring(index+1);&lt;br /&gt;
&lt;br /&gt;
            if (paramKey.toLowerCase() == "tipo") { paramTipo = paramValue; }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/em&gt;Ya solamente quedará utilizar adecuadamente en nuestro código &lt;strong&gt;actionscript&lt;/strong&gt; la variable definida aquí como&lt;em&gt; &lt;strong&gt;paramTipo&lt;/strong&gt;&lt;/em&gt; para la finalidad que fuera necesaria. Con esto lo que logramos, como ya hemos comentado, es poder cambiar dinámicamente nuestra película flash en función de los valores que se han introducido en el &lt;strong&gt;QueryString&lt;/strong&gt;, lo cual nos abre un abanico de posibilidades realmente amplio.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Este &lt;strong&gt;Script&lt;/strong&gt; solamente funcionará en &lt;strong&gt;Internet Explorer&lt;/strong&gt; si nuestro &lt;strong&gt;.swf&lt;/strong&gt; integrado en el &lt;strong&gt;HTML&lt;/strong&gt; como un &lt;strong&gt;Object&lt;/strong&gt; emebedido tiene previamente definido un &lt;strong&gt;id&lt;/strong&gt;.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
Podréis encontrar más información ampliada en inglés en los siguientes enlaces.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Fuente 1&lt;/strong&gt; | &lt;a href="http://blog.circlecube.com/2008/03/20/get-current-url-and-query-string-parameters-to-flash-tutorial/" title="Circlecube.com" target="_blank"&gt;Circlecube.com&lt;/a&gt; &lt;br /&gt;
&lt;strong&gt;Fuente 2&lt;/strong&gt; | &lt;a href="http://www.permadi.com/tutorial/flashQueryString/index.html" title="Permadi.com" target="_blank"&gt;Permadi.com&lt;/a&gt;&lt;br /&gt;
</description>
      <link>http://www.avanzis.com/blogs/javier-belmonte/i/8529/805/trucos-flash-obtencion-de-variables-desde-querystring</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/javier-belmonte/i/8529/805/trucos-flash-obtencion-de-variables-desde-querystring</guid>
      <pubDate>Tue, 12 Aug 2008 14:30:19 GMT</pubDate>
    </item>
    <item>
      <title>Recomendaciones: Pasar de HTML a XHTML (I)</title>
      <description>En muchas ocasiones, cuando se aborda un cambio en el &lt;strong&gt;lenguaje de marcado&lt;/strong&gt; utilizado habitualmente para crear nuestras &lt;strong&gt;páginas webs&lt;/strong&gt;, como es por ejemplo el paso de &lt;strong&gt;HTML&lt;/strong&gt; a &lt;strong&gt;XHTML&lt;/strong&gt;, frecuentemente nos encontramos con problemas de varios tipos, &lt;strong&gt;atributos&lt;/strong&gt; usados de forma indebida, &lt;strong&gt;etiquetas&lt;/strong&gt; mal cerradas, e incluso en algunos casos el comportamiento de los &lt;strong&gt;CSS&lt;/strong&gt; varía, con lo que hay que volver revisarlos y redefinirlos.&lt;br /&gt;
&lt;br /&gt;
Puede parecer, y no falta razón en ocasiones, que los que diseñamos y creamos &lt;strong&gt;páginas web&lt;/strong&gt; ante un cambio de &lt;strong&gt;lenguaje de marcado&lt;/strong&gt;, no nos paramos ni un segundo a estudiar las nuevas reglas de uso y que nos limitamos a dejar que el día a día sea el que nos muestre esos nuevos cambios. Algo que puede tener su origen quizás, en nuestra condición de &lt;i&gt;autodidactas&lt;/i&gt;, al menos en mi caso. Ignoro si en el mundo de la programación sucede igual, pero para los que hacemos &lt;strong&gt;páginas web&lt;/strong&gt; creo que éste es uno de nuestros mayores hándicaps, la falta de concienciación sobre las reglas de nuestro &lt;strong&gt;lenguaje de marcado&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
Ni que decir tiene que el &lt;strong&gt;lenguaje de marcado&lt;/strong&gt; que vayamos a utilizar influye de manera crítica en la forma que nuestro navegador va a interpretar los &lt;strong&gt;CSS&lt;/strong&gt;, una de las piedras angulares sobre los que sustentan nuestros &lt;strong&gt;diseños&lt;/strong&gt; y nuestras &lt;strong&gt;páginas web&lt;/strong&gt;. Es por ello por lo que no está de más conocer cuáles son algunos de los cambios más importantes que &lt;strong&gt;XHTML&lt;/strong&gt; ha incorporado, sobre todo si no queremos que nos afecte a nuestros &lt;strong&gt;CSS&lt;/strong&gt;. &lt;br /&gt;
&lt;br /&gt;
Por ejemplo, una de las nuevas características de &lt;strong&gt;XHTML&lt;/strong&gt; es que es &lt;strong&gt;case sensitive&lt;/strong&gt;. Podríamos pensar que ahí reside uno de los mayores conflictos con &lt;strong&gt;CSS&lt;/strong&gt;, pero este cambio introducido en &lt;strong&gt;XHTML&lt;/strong&gt;, no representa muchas diferencias con lo que se venía haciendo, ya que en &lt;strong&gt;HTML&lt;/strong&gt; la definición de atributos &lt;strong&gt;id &lt;/strong&gt;y &lt;strong&gt;class&lt;/strong&gt; también era &lt;strong&gt;case sensitive&lt;/strong&gt;. &lt;br /&gt;
&lt;br /&gt;
Entonces, ¿por qué el paso de un documento &lt;strong&gt;HTML&lt;/strong&gt; a &lt;strong&gt;XHTML&lt;/strong&gt; deriva en todos estos inconvenientes? La respuesta la podemos encontrar fácilmente en la forma que han tenido y tienen los &lt;strong&gt;navegadores de Internet&lt;/strong&gt; de interpretar el documento que se está abriendo.&lt;br /&gt;
&lt;br /&gt;
La correcta definición en la cabecera de los tipos de los documentos utilizados, ya sean &lt;strong&gt;HTML&lt;/strong&gt; o &lt;strong&gt;XHTML&lt;/strong&gt;, ha sido una práctica poco habitual en el mundo &lt;strong&gt;web&lt;/strong&gt;. Actualmente se ha convertido en algo realmente necesario, sobre todo para que los &lt;strong&gt;navegadores&lt;/strong&gt; apliquen correctamente los estándares y sepan interpretar los documentos de la forma adecuada. &lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Ejemplo:&lt;/strong&gt; Definición de un documento de tipo XHTML 1.0 Transitional.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd"&gt;&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
La ausencia de esta definición, derivaba en un conflicto realmente importante con los &lt;strong&gt;navegadores de Internet&lt;/strong&gt;, quienes al desconocer el tipo de documento que estaban procesando, y en lugar de usar al azar alguno de los estándares definidos, el &lt;strong&gt;Standar Mode&lt;/strong&gt;, adoptaban el modo de compatibilidad por defecto, o más conocido como &lt;strong&gt;Quirks Mode&lt;/strong&gt;. &lt;br /&gt;
&lt;br /&gt;
Una de las particularidades de este modo era precisamente no ser &lt;strong&gt;case sensitive&lt;/strong&gt;. Esto afectaba, y sigue afectando, no sólo a la forma de visualizar e interpretar las &lt;strong&gt;páginas web&lt;/strong&gt;, sino a la forma en la que los que desconocían esta circunstancia generaban su &lt;strong&gt;código CSS&lt;/strong&gt;. Siempre ha existido, o al menos esa es mi impresión, la tendencia de diseñar para los &lt;strong&gt;navegadores&lt;/strong&gt;, sin pensar que la solución pasa por diseñar pensando en los estándares. Unos estándares que los propios &lt;strong&gt;navegadores&lt;/strong&gt; ya son capaces de interpretar a la perfección a poco que se lo indiquemos de forma adecuada.&lt;br /&gt;
&lt;br /&gt;
Podríamos decir pues que, al margen de la experiencia de cada uno, no hay nada mejor que saber y conocer perfectamente las reglas, particularidades y características fundamentales del &lt;strong&gt;lenguaje de marcado&lt;/strong&gt; que estamos utilizando. Pero además debemos ser capaces de ver a los &lt;strong&gt;navegadores de Internet&lt;/strong&gt; como lo que son, unos simples intérpretes de nuestro código. &lt;br /&gt;
&lt;br /&gt;
Así, cuando nos topemos de nuevo con la disyuntiva, más que habitual hoy día, de que &lt;strong&gt;IE6, IE7, FF2 y FF3&lt;/strong&gt; no muestran nuestra &lt;strong&gt;página web&lt;/strong&gt; de la misma forma, sabremos reconocer que quizás el problema sea simplemente que no hemos sabido utilizar de forma adecuada todos los &lt;strong&gt;estándares&lt;/strong&gt;, &lt;strong&gt;herramientas&lt;/strong&gt; y &lt;strong&gt;lenguajes&lt;/strong&gt; de los que disponemos. 
</description>
      <link>http://www.avanzis.com/blogs/javier-belmonte/i/8504/805/recomendaciones-pasar-de-html-a-xhtml-i</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/javier-belmonte/i/8504/805/recomendaciones-pasar-de-html-a-xhtml-i</guid>
      <pubDate>Sun, 10 Aug 2008 13:39:36 GMT</pubDate>
    </item>
    <item>
      <title>Scrum, Test Driven Development y MVC. Vamos a ser ágiles.</title>
      <description>En Avanzis estamos empezando un proyecto que nos ilusiona mucho, y que esperamos que vea la luz antes de final de año. Como todo proyecto que empieza, uno de los primeros aspectos a decidir es qué metodología vamos a seguir y qué plataforma tecnológica. En este proyecto vamos a utilizar &lt;a href="http://es.wikipedia.org/wiki/Scrum"&gt;Scrum&lt;/a&gt; y &lt;a href="http://es.wikipedia.org/wiki/Tdd"&gt;Test Driven Development&lt;/a&gt;. Vale. Y ahora os preguntareis ¿esto qué significa?. Pues básicamente son dos relativamente nuevas metodologías en el desarrollo de software, clasificadas dentro de las llamadas “ágiles”. Estas dos metodologías tienen algo en común. Se asume que el diseño de la arquitectura de clases, la definición de las funcionalidades y la especificación de requisitos, es un proceso que fluye a través de todo el desarrollo del proyecto, y no son una etapa inicial aislada. No hay que esperar a tener el diseño y la especificación completa para empezar a desarrollar. Scrum es una manera de organizarse, y TDD es una manera de desarrollar.     &lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;¿Qué es SCRUM?&lt;/strong&gt; &lt;br /&gt;
&lt;br /&gt;
Scrum es una metodología de trabajo ágil, especialmente diseñada para intentar acortar los ciclos de desarrollo y conseguir una mejor aproximación entre las funcionalidades del software y los requerimientos del cliente. Se trata de evitar la burocracia innecesaria,  conseguir una mayor versatilidad frente a los cambios y empezar rápidamente a trabajar, de manera que el cliente puede ir viendo lo antes posible los avances en el proyecto. Es óptima para equipos de trabajo no demasiado grandes y clientes que tengan un alto grado de implicación en el proyecto. El procedimiento básico consiste en crear un repositorio con las funcionalidades requeridas para el proyecto, asignándoles unos puntos de importancia, una estimación en horas y cómo se debe demostrar esta funcionalidad. A esto lo llamaremos “Product Backlog”. A partir de entonces, se crean los “Sprint Backlogs”, que son un conjunto de tareas que se deben completar en un determinado tiempo, entre 2 semanas y un mes. Durante cada dia del sprint, se hace una corta reunión para revisar el estado de las tareas, y al final de cada sprint, una reunión con el cliente para mostrarle los resultados. Así, el cliente va viendo los avances cada corto periodo de tiempo, y se puede reajustar cualquier cambio de funcionalidad en cualquier etapa del proyecto. Obtenemos un feedback que nos permite mejorar en el siguiente sprint. &lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;¿Qué es TDD?&lt;/strong&gt;&lt;br /&gt;
 &lt;br /&gt;
Para tratar de mejorar del código, existen los  “&lt;a href="http://en.wikipedia.org/wiki/Unit_testing"&gt;Unit Tests&lt;/a&gt;”, que consisten en código adicional que se ocupa de probar el código principal. Se trata de probar que pequeñas unidades individuales de código se comportan tal y como esperamos. Para ello existen frameworks como &lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt; con el fin de ayudarnos en esta tarea. Mediante los test, tenemos una mayor seguridad en que las cosas funcionan como deben, y además, podemos comprobar que las cosas siguen funcionando bien después de hacer cambios en el código. Pero TDD va más allá. En lugar de programar y luego probar, se intercambia el orden, de manera que primero creamos los test, y a partir de aquí se va creando la funcionalidad. El ciclo que se va repitiendo es: Añadir el test para una nueva funcionalidad. Evidentemente, este test fallará dado que la funcionalidad no está implementada. Programaremos, ejecutaremos todos los tests hasta que todos ellos tengan éxito, y finalmente refactorizaremos y volveremos a empezar. En el modelo habitual, se dedica una parte muy importante del tiempo diseñando completamente los modelos lógicos y físicos antes de escribir ninguna línea de código. Sin embargo, con este modelo, el diseño se deriva de los test de funcionalidad, y es un proceso que discurre al mismo tiempo que el propio desarrollo. Por esto, está metodología de desarrollo encaja perfectamente en la metodología organizativa SCRUM. &lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;MVC&lt;/strong&gt; &lt;br /&gt;
&lt;br /&gt;
Finalmente, teníamos que elegir una plataforma tecnológica para desarrollar el proyecto siguiendo esta metodología. Para ello, hemos elegido seguir el patrón &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;Model View Controller&lt;/a&gt; , y en concreto la implementación de &lt;a href="http://www.asp.net/mvc/"&gt;asp.net MVC&lt;/a&gt;. Las metodologías anteriores se pueden utilizar con cualquier plataforma, pero MVC proporciona un modelo ideal para realizar los test de una manera mucho más completa, probando no solo la lógica sino también la interacción con la interfaz de usuario. Pero sobre MVC, ya hablaremos en detalle en próximos posts. &lt;br /&gt;
&lt;br /&gt;
Así que ya sabéis, durante un tiempo, hablaremos de nuestras experiencias con SCRUM, TDD y MVC.
</description>
      <link>http://www.avanzis.com/blogs/josep-planells/i/8292/834/scrum-test-driven-development-y-mvc-vamos-a-ser-agiles</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/josep-planells/i/8292/834/scrum-test-driven-development-y-mvc-vamos-a-ser-agiles</guid>
      <pubDate>Thu, 24 Jul 2008 00:42:49 GMT</pubDate>
    </item>
    <item>
      <title>Lucene para ASP.NET (Parte III). Búsqueda. </title>
      <description>Siguiendo la serie de artículos sobre &lt;strong&gt;Lucene &lt;/strong&gt;(&lt;a href="http://www.avanzis.com/blogs/xavi-navarro/i/7596/831/lucene-para-asp-net-parte-i-introduccion"&gt;Lucene para ASP.NET (Parte I). Introducción&lt;/a&gt; y &lt;a href="http://www.avanzis.com/blogs/xavi-navarro/i/7803/831/lucene-para-asp-net-parte-ii-indexacion"&gt;Lucene para ASP.NET (Parte II). Indexación&lt;/a&gt;), dónde conocimos qué era Lucene y cómo &lt;strong&gt;indexar contenidos&lt;/strong&gt;, durante este artículo vamos a hablar de la búsqueda, sin duda, el objetivo último que perseguimos.&lt;br /&gt;
&lt;br /&gt;
Según la estructura del &lt;strong&gt;Document &lt;/strong&gt;planteada en el artículo sobre &lt;a href="http://www.avanzis.com/blogs/xavi-navarro/i/7803/831/lucene-para-asp-net-parte-ii-indexacion"&gt;Indexación&lt;/a&gt;, cuando queramos buscar algo atacaremos a los campos "Title" y "Text", pues son los que contendrán la información importante. Es decir, lo que queremos es "buscar palabras que se encuentran en el título o en el texto".&lt;br /&gt;
&lt;br /&gt;
A continuación tenemos un método que busca en ambos campos y devuelve un listado de Document's:&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;public static List&lt;Document&gt; SearchDocuments(string sQuery)&lt;br /&gt;
{&lt;br /&gt;
    // Creamos el listado documents que vamos a devolver&lt;br /&gt;
    List&lt;Document&gt; documents = new List&lt;Document&gt;();&lt;br /&gt;
    &lt;br /&gt;
    // Abrimos el IndexSearcher con el Path del directorio que  hace de índice. Aquí usamos una variable global.&lt;br /&gt;
    IndexSearcher searcher = new IndexSearcher(IndexPath);&lt;br /&gt;
&lt;br /&gt;
    try&lt;br /&gt;
    {&lt;br /&gt;
        // Buscamos en Text&lt;br /&gt;
        QueryParser qpText = new QueryParser("Text", new SpanishAnalyzer());&lt;br /&gt;
        Query queryText = qpText.Parse(sQuery);&lt;br /&gt;
&lt;br /&gt;
        // Buscamos en Title&lt;br /&gt;
        QueryParser qpTitle = new QueryParser("Title", new SpanishAnalyzer());&lt;br /&gt;
        Query queryTitle = qpTitle.Parse(sQuery);&lt;br /&gt;
&lt;br /&gt;
        // Unimos ambos elementos: queremos que nuestro query se encuentre en uno de los dos sitios. &lt;br /&gt;
        // Si puede ser en los dos, mejor.&lt;br /&gt;
        BooleanQuery bq = new BooleanQuery();&lt;br /&gt;
        bq.Add(queryText, BooleanClause.Occur.SHOULD);&lt;br /&gt;
        bq.Add(queryTitle, BooleanClause.Occur.SHOULD);&lt;br /&gt;
&lt;br /&gt;
        // La clase Hits es la clave. Es lo que nos devolverá la Search&lt;br /&gt;
        Hits hits = searcher.Search(bq);&lt;br /&gt;
        int totalHits = hits.Length();&lt;br /&gt;
&lt;br /&gt;
        // Recorremos todos los Hits, recogemos el document y lo añadimos a nuestro listado genérico&lt;br /&gt;
        // Aquí es donde debería hacerse la paginación, etc.&lt;br /&gt;
        for (int i = 0; i &lt; totalHits; i++)&lt;br /&gt;
        {&lt;br /&gt;
            Document document = hits.Doc(i);&lt;br /&gt;
            documents.Add(document);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    finally&lt;br /&gt;
    {&lt;br /&gt;
        searcher.Close();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return documents;&lt;br /&gt;
}&lt;br /&gt;
&lt;/em&gt;&lt;br /&gt;
Como vemos, el código se autoexplica bastante.&lt;br /&gt;
&lt;br /&gt;
Lo más importante es saber que &lt;em&gt;QueryParser &lt;/em&gt;define dónde queremos buscar y con qué Analyzer, y &lt;em&gt;Query &lt;/em&gt;define qué queremos buscar.&lt;br /&gt;
&lt;br /&gt;
Con el BooleanQuery uniremos las búsquedas en ambos campos, indicándole mediante el SHOULD que los resultados deben encontrarse en al menos uno de los dos campos (Title o Text), pero que si puede ser en los dos, mejor que mejor.&lt;br /&gt;
&lt;br /&gt;
Los resultados tras el searcher.Search(...) vienen en forma de Hits. Los Hits contienen el Document, pero también contienen otros campos interesantes como el Score que devuelve la puntuación de 0 a 100 o el Length que devuelve el número de resultados encontrados.&lt;br /&gt;
&lt;br /&gt;
Como véis esto ha sido una búsqueda a pelo. Ahora quedaría paginar, filtrar los resultados con Score bajo, etc.&lt;br /&gt;
</description>
      <link>http://www.avanzis.com/blogs/xavi-navarro/i/8245/831/lucene-para-asp-net-parte-iii-busqueda</link>
      <guid isPermaLink="true">http://www.avanzis.com/blogs/xavi-navarro/i/8245/831/lucene-para-asp-net-parte-iii-busqueda</guid>
      <pubDate>Tue, 22 Jul 2008 10:36:29 GMT</pubDate>
    </item>
  </channel>
</rss>