Noticias Weblogs Foros Wiki Código

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin

mundoxbase.info

Diciembre 23rd, 2011 - [Enlace local]

目当てのキーワードを各検索エンジンで効率よく検索結果にのせるには、力任せに登録するのではなく注意深く準備のもとに意図のある登録を行うべきです。

» Leer más, comentarios, etc...

mundoxbase.info

Diciembre 23rd, 2011 - [Enlace local]

また近年までは検索エンジンでの順位に大きく影響する要因はサイト内部の出来不出来よりも外部の比率が大きかったため、それほどコンテンツが良くないサイトであったとしても適切な被リンク対策により相当の位置まで上位表示出来ましたが、このところ色々な条件を整えることは必須条件になっているため既に単純な外部構築だけで上位化することはとても難しくなってきています。

» Leer más, comentarios, etc...

mundoxbase.info

Diciembre 23rd, 2011 - [Enlace local]

これはそのサイトにまとめられたコンテンツが訪れる人にとって有益であるかどうかや正しいコードが書いてあるかなどサイト内の点数と、そこにある内容が他者からどんなリンクテキストでどのくらい多く被リンクを受けているか?といったサイト外要因があります。

» Leer más, comentarios, etc...

mundoxbase.info

Diciembre 23rd, 2011 - [Enlace local]

検索エンジンの検索結果(SERPs)は検索ユーザーがサーチボックスに入力した内容へもっとも相応と思われる答えを返そうとしますが、その時の表示される順番は大別すると2つの条件で決まります。

» Leer más, comentarios, etc...

mundoxbase.info

Diciembre 23rd, 2011 - [Enlace local]

当サイトに掲載しているヨミサーチは静的なhtmlページから直に掲載サイトにリンクする小規模なディレクトリで、自サイト内に検索ディレクトリを設ける目的で採用されるCGIを比べた場合、もっとも有効性があるため非常にたくさんのサイトに使われています。

» Leer más, comentarios, etc...

mundoxbase.info

Diciembre 23rd, 2011 - [Enlace local]

登録ディレクトリmundoxbase.infoサーチには法的に問題あるコンテンツが記載されているページや青少年にとって問題があるページは不承認とするケースがあります。
また本サイト管理者が他者に不快感を感じさせると感じた時には、連絡をせずに管理人裁断によって削除させていただきます。

» Leer más, comentarios, etc...

Koalite's blog

Tratar con Proxies en Castle Windsor

Diciembre 22nd, 2011 - [Enlace local]

Cuando estás usando Dynamic Proxy, ya sea directamente o para aplicar AOP con Castle Windsor, a veces es necesario distinguir si una instancia de un objeto es una instancia real o un proxy generado.

Esto es frecuente cuando desde la infraestructura de la aplicación necesitamos acceder a metainformación de alguna clase, por ejemplo, el espacio de nombres en que está declarada, si tiene algún atributo, etc.

Si estamos usando proxies como los que genera Windsor al crear los interceptores, la instancia que tenemos pertenece a una clase generada al vuelo que actúa como decorador de la instancia real, por lo que no tenemos una forma directa de obtener el tipo real para acceder a esa metainformación.

Esto lo podemos solventar usando el interface IProxyTargetAccessor, que es implementado por todas los proxies generados por Dynamic Proxy y nos permite acceder a la instacia real:

var proxy = GetSomeProxy();
var actualInstance = (proxy as IProxyTargetAccessor).DynProxyGetTarget();

Sin embargo, existe una alternativa mucho mejor: utilizar la clase ProxyUtil, que nos permite:

Compartir enlace:
Facebook Twitter Email

Posts relacionados:

  1. AOP con Castle Windsor: IInterceptor
  2. Configurar decoradores en Castle Windsor
  3. Aplicaciones modulares con Castle Windsor: IHandlerSelector

» Leer más, comentarios, etc...

Picando Código

ArchLinux: Actualización de filesystem requiere intervención manual

Diciembre 21st, 2011 - [Enlace local]

ArchLinux

ArchLinux

Hace tiempo que no posteo nada sobre ArchLinux, así que les comento de una nueva actualización. En general los usuarios de Arch venimos acostumbrados a prestar atención a las noticias del sistema. Al ser un sistema de actualización constante, algunas veces tenemos que intervenir la instalación de actualizaciones a mano. Pero de todas formas por las dudas hago eco del aviso por acá para los usuarios de Arch que me leen.

Esta actualización en cuestión está disponible desde ayer, y refiere al paquete filesystem. Cuando actualicemos  a filesystem-2011.12, habrá un conflicto en /etc/mtab. Para continuar, hay que forzar a pacman a instalar el paquete de la siguiente manera:

pacman -S filesystem --force

Los aministradores del sitio de Arch recuerdan que es recomendable evitar usar la opción –force o -f ya que no es seguro. Pero en este caso en particular es necesario porque borrar /etc/mtab manualmente rompería pacman. La razón del conflicto es que el archivo solía ser generado al inicio del sistema y no pertenecía a ningun paquete. Ahora es un link simbólico a /proc/self/mounts que pertenece a filesystem.

La noticia en el sitio oficial de ArchLinux:
News: filesystem upgrade – manual intervention required

» Leer más, comentarios, etc...

Variable not found

IMetadataAware, atributos de metadatos personalizados

Diciembre 20th, 2011 - [Enlace local]

ASP.NET MVCHace pocas semanas profundizamos en los mecanismos de obtención de metadatos del modelo en ASP.NET MVC y vimos cómo extender el framework para dotarlo de vías alternativas desde las que obtener esta información usando un proveedor personalizado.



Sin embargo, no es este el único mecanismo de extensión del framework a este respecto: también podemos crear fácilmente nuevos atributos que aporten información extra de metadatos a las clases y propiedades del Modelo. Y esta es la razón de ser del interfaz IMetadataAware.



El interfaz IMetadataAware

Definido en System.Web.Mvc e introducido con la tercera versión del framework, este interfaz permite crear atributos que encajen muy suavemente en el sistema de generación y obtención de metadatos de ASP.NET MVC, evitando en muchos escenarios la necesidad de escribir proveedores personalizados.

Como podemos ver a continuación, su definición es de lo más simple:

public interface IMetadataAware
{
    void OnMetadataCreated(ModelMetadata metadata);
}
ModelMetadata (parcial)¿Y cómo se utiliza esto internamente? Pues la respuesta la podemos encontrar buceando un poco en el código fuente del framework.



Durante el proceso de obtención de metadatos, el proveedor DataAnnotationsModelMetadataProvider (en conjunción con su tipo base AssociatedMetadataProvider), obtiene los metadatos “estándar” y los introduce en un objeto de tipo ModelMetadata.



Una vez tenemos ya esta información, obtenida según el comportamiento por defecto desde los atributos conocidos que decoran las propiedades del Modelo, se ejecuta el método estático ApplyMetadataAwareAttributes(), que tiene la siguiente pinta:

private static void ApplyMetadataAwareAttributes(
                          IEnumerable<Attribute> attributes, 
                          ModelMetadata result)
{
    foreach (IMetadataAware awareAttribute in attributes.OfType<IMetadataAware>())
    {
        awareAttribute.OnMetadataCreated(result);
    }
} 
Como se puede deducir a la vista del código, el método es invocado suministrándole, por una parte, todos los atributos localizados en la clase del Modelo, y por otra, el objeto ModelMetadata que contiene la información de metadatos obtenidos hasta el momento.



Ya en su interior, lo único que se hace es obtener todos aquellos atributos que implementen el interfaz IMetadataAware y llamar a su único método OnMetadataCreated() con objeto de que actualicen los metadatos con la información que necesiten.



Por tanto, en la práctica, si queremos crear un atributo que introduzca información adicional de metadatos, o simplemente modifique los existentes, debemos:

Por ejemplo:

public class MyMetadataAttribute: Attribute, IMetadataAware
{
    public void OnMetadataCreated(ModelMetadata metadata)
    {
        // Set properties...
        metadata.DisplayName = "My text";
 
        // ... or add new properties to AdditionalValues
        metadata.AdditionalValues["MyKey"] = "My value";
    }
}
Observad que en el cuerpo del método tenemos acceso a todas las propiedades de metadatos, así como a su diccionario AdditionalValues, donde podemos introducir cualquier tipo de información que nos interese poner a disposición de la Vista.

¿Un ejemplo rápido?

Vamos a desarrollar un atributo de metadatos personalizado al que llamaremos Important, y que hará lo siguiente:

(Ojo, que hay otras formas para conseguir este mismo resultado, pero el post trata sobre IMetadataAware, así que tendremos que quedarnos con esta ;-))

public class ImportantAttribute: Attribute, IMetadataAware
{
    public void OnMetadataCreated(ModelMetadata metadata)
    {
        metadata.DisplayName = metadata.GetDisplayName() + " (important!)";
        metadata.AdditionalValues["Important"] = true;
    }
}
Eso es todo lo que necesitamos en nuestro atributo. Hecho esto, ya podemos utilizarlo en una clase del Modelo como se muestra a continuación:

public class Friend
{
    [Important]
    public string Name { get; set; }
 
    public string Email { get; set; }
 
    [Important]
    public string Phone { get; set; }
 
    public string Fax { get; set; }
 
}
El simple hecho de decorar las propiedades Name y Phone con nuestro flamante atributo [Important] hará que sus etiquetas descriptivas aparezcan ya con el sufijo “important!”, puesto que estamos modificando directamente su DisplayName. Si queremos además destacar los editores necesitaremos inyectar un poco de lógica en la vista, cosa que podemos hacer de forma relativamente sencilla implementando un helper o modificando las plantillas de edición por defecto para los tipos utilizados (en este caso, strings).



Una implementación rápida de un helper que genere código script para destacar las propiedades importantes podría ser la siguiente. Si os fijáis, lo único que hace es obtener aquellas propiedades en cuyos metadatos exista la entrada de AdditionalValues establecida en el atributo [Important], y establecer en sus editores la clase CSS “important” para darles un poco de color:

public static class HtmlExtensions
{
    public static MvcHtmlString HighlightImportant(this HtmlHelper html)
    {
        var template = html.ViewData.TemplateInfo;
        var importantProps = from property in html.ViewData.ModelMetadata.Properties
                                where property.AdditionalValues.Any(
                                    a => a.Key == "Important" && (bool)a.Value)
                                select template.GetFullHtmlFieldId(property.PropertyName);
                                       
        if (importantProps.Any())
        {
            string commaIds = string.Join(",#", importantProps);
            string script = "<script type='text/javascript'>" +
                            "$(function() { $('#" + commaIds + "').addClass('important'); });" +
                            "</script>";
            return MvcHtmlString.Create(script);
        }
        return null;
    }
}
El atributo Important en acciónObviamente, tendríamos que incluir una llamada al helper Html.HighlightImportant() en las vistas o, si queremos mayor comodidad, en el Layout del sitio web.



En la captura de pantalla de la derecha podéis ver el resultado de este ejemplo en funcionamiento. Y si queréis probarlo y juguetear un rato con él, podéis descargar el proyecto para Visual Studio y ASP.NET MVC 3 desde mi Skydrive.





Publicado en Variable not found.



» Leer más, comentarios, etc...

Joan Llenas at garnet.io :: Thoughts on software development

Información detallada acerca de Apache Flex

Diciembre 19th, 2011 - [Enlace local]

Un montón de cosas están pasando alrededor del anuncio de Adobe de donar Flex a la Apache Software Foundation.
No voy a tratar de resumir el estado del proceso de transición, en cambio voy a apuntar a un enlace que resume muy bien todo lo sucedido los últimos días.

» Leer más, comentarios, etc...

Picando Código

Aprendiendo HAML

Diciembre 19th, 2011 - [Enlace local]

Haml - markup haiku

Haml - markup haiku

Una de las tantas cosas que “me llevé anotadas para aprender” de la pasada RubyConf Uruguay fue HAML.

En Ruby se usa mucho ERB como sistema de plantillas para crear archivos HTML con código Ruby embebido. Lo mismo que provee JSP o PHP. Ahora, el “tema” con erb, es que a pesar de permitir ejecutar código Ruby, uno está obligado a escribir el código HTML.

Ahí entra HAML, un lenguaje de marcado ligero con el cual podemos generar HTML a partir de un sencillo DSL. Haml busca emprolijar las plantillas y deshacerse de los lenguajes “feos” que venimos utilizando en nuestras plantillas HTML. Me resultó sumamente útil para desarrollo web en general, no solo para usar con Ruby.

El código que usa es realmente elegante, lo que se explica con uno de sus principios primarios: El marcado debería ser hermoso.

Haml es una solución real a un problema real. Deja de usar las plantillas lentas, repetitivas y molestas que ni siquiera conoces cuánto odias todavía. Prueba algo nuevo – haz que las plantillas sean divertidas y bellas de nuevo.

Haml puede ser usado dentro de una aplicación web o por su cuenta. Por ejemplo podemos incluirlo en aplicaciones que usan Rails o Sinatra, así como también generar las plantillas desde línea de comando con haml “suelto”.

Por ejemplo si tenemos el siguiente archivo index.html.haml:

!!!
%html
  %head
    %title Página de inicio
  %body
    %h1 Bienvenidos a la página de inicio
    %p Esto es un párrafo de texto
    %ul.menu
      %li Primer elemento
      %li Segundo elemento

Podemos usar Haml por línea de comando:

[fernando@hoth ror]$ haml index.html.haml index.html

Lo que nos generará el archivo index.html:


<html>
  <head>
    <title>Página de inicio</title>
  </head>
  <body>
    <h1>Bienvenidos a la página de inicio</h1>
    <p>Esto es un párrafo de texto</p>
    <ul class='menu'>
      <li>Primer elemento</li>
      <li>Segundo elemento</li>
    </ul>
  </body>
</html>

Como dice en el sitio web, aprender Haml es muy fácil y no toma más de 20 minutos. Incluso invitan a los desarrolladores a probar de convertir uno de sus archivos ERB a Haml: “Siente el poder de la tecla Suprimir. Simplifica. Disfruta. Ríete. 20 minutos después, nunca volverás.”

Realmente es más rápido, sencillo y elegante que ERB. El ejemplo que muestran en el sitio de inicio de Haml es bastante gráfico:

HAML

#profile
  .left.column
    #date= print_date
    #address= current_user.address
  .right.column
    #email= current_user.email
    #bio= current_user.bio

ERB

<div id="profile">
  <div class="left column">
    <div id="date"><%= print_date %></div>
    <div id="address"><%= current_user.address %></div>
  </div>
  <div class="right column">
    <div id="email"><%= current_user.email %></div>
    <div id="bio"><%= current_user.bio %></div>
  </div>
</div>

Como ven, es bastante sencillo darse cuenta cómo funciona. Generar tags con .clases e #id’s css es muy sencillo. Algo particular que tiene es que usa una sintaxis al estilo Python, en el sentido que no hay que cerrar los tags, simplemente se cierran por indentación. Les recomiendo el tutorial -van a ver que salen andando con Haml en unos pocos minutos- y seguir con la referencia. Hay soporte para varios editores de Texto.

Para poner en práctica los conocimientos, decidí pasar mi sitio web personal de ERB a Haml. La web fernandobriano.com es algo así como un Sandbox de Rails para ir aplicando cosas que quiera aprender a usar. Solía tener un archivo HTML plano con links a los blogs, Linkedin y demás, pero ahora la estoy usando como excusa para desarrollar algo con Ruby de vez en cuando. Si quieren ver el código fuente, está colgado en github: https://github.com/picandocodigo/fb_site

» Leer más, comentarios, etc...

Picando Código

Gimp 2.7.4 – se acerca Gimp 2.8

Diciembre 19th, 2011 - [Enlace local]

GIMP 2.7.4

GIMP 2.7.4

Recientemente se actualizó la versión de desarrollo de GIMP a 2.7.4. Si bien no tengo mucha experiencia (probablemente tampoco habilidad) en el campo del diseño gráfico, GIMP ha sido mi programa de edición de imágenes desde hace unos cuantos años.

Creo (y muchos estarán de acuerdo) que uno de los mayores problemas de GIMP para obtener una adopción masiva, era el uso de varias ventanas. Con la versión 2.8, este problema se corrige, contando con un modo ventana única opcional. También se mantiene el modo de varias ventanas al que ya habrán usuarios acostumbrados.

Vengo usando GIMP en versión desarrollo desde los primeros builds. La versión 2.7 incluye los cambios que se van incluyendo para lo que será la versión final 2.8. Desde entonces, me siento mucho más cómodo usando GIMP con modo ventana única, y me cuesta volver a usar GIMP 2.6.

Con la versión mas reciente de 2.7, se agregan algunos cambios importantes de UI muy bienvenidos. En primer lugar se cambió el splash screen. Probablemente no sea el definitivo, pero me gusta mucho más que el controversial splash screen anterior.

Se agregó un botón de cerrar a las tabs de imágenes en el modo de ventana simple. Antes había que cerrar desde el mismo botón de “cerrar la aplicación”, o con el atajo Ctrl+W. Ahora cada pestaña tiene su botón de cerrar :)

Pestañas en Gimp 2.7.4

Pestañas en Gimp 2.7.4

Las sesiones de ventana única o ventana múltiple se guardan de manera consistente en sessionrc. Esto venía siendo un problema en versiones anteriores, ya que a veces el programa se cerraba con modo ventana única, pero volvía a modo múltiple o viceversa al re iniciar.

Pueden ver todos los cambios de la versión en este enlace.

Repito acá algo que escribí en uno de los primeros posts sobre GIMP ventana única, palabras de mi amigo Máximo:

“el fabuloso e inusable Gimp, el cual si bien valga la redundancia es pobre muy pobre en cuanto a usabilidad, es muy potente”
Recomiendo leer el resto en: La practica hace al maestro, no sus herramientas.

Pueden descargar Gimp 2.7.4 desde el siguiente enlace:

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 64

Diciembre 19th, 2011 - [Enlace local]

Enlaces interesantes: .NET, ASP.NET, Azure, HTML, CSS, Visual StudioEstos son los enlaces publicados en Variable not found en Facebook y Twitter del 12 al 17 de diciembre de 2011. Espero que os resulten interesantes. :-)



Aprovecho además para pediros opinión sobre un nuevo formato de presentación de los enlaces, usando categorizaciones. De esta forma podréis acceder directamente a aquellos cuya temática os interese, en lugar de tener que leerlos todos para ver si hay alguno que al que valga la pena echar el vistazo. ¿Qué os parece? ¿Mejor así?

.Net

Asp.net

Azure / Cloud

Conceptos

Data access

Html/Css/Javascript

Visual Studio/Complementos

Otros

Y no olvidéis que podéis seguir esta información en vivo y en directo desde Variable not found en Facebook, o a través de Twitter.



Publicado en Variable not found



» Leer más, comentarios, etc...

Variable not found

[Auges] Inyección de dependencias en ASP.NET

Diciembre 19th, 2011 - [Enlace local]

AugesMañana, martes 20 de diciembre de 2011, a las 19:00h (GMT+1) en AUGES tendremos el placer de contar con la presencia de Luis Ruiz Pavón, alma mater del grupo y gran conocido en la comunidad de desarrolladores .NET, para explicarnos qué es, para qué sirve y cómo se usa la Inyección de Dependencias, especialmente enfocado al desarrollo con ASP.NET.

En este WebCast veremos una introducción a la inyección de dependencias en ASP.NET con ejemplos prácticos:



Ponente:
Luis Ruiz Pavón (Spenta - Beezy) - miembro y fundador de AUGES (www.auges.org) y uno de los grandes colaboradores de la comunidad de desarrolladores. Puedes seguirlo a través de su blog técnico (www.luisruizpavon.com) y de Twitter (@luisruizpavon).
Como siempre, se trata de un Webcast de asistencia es gratuita al que podéis registraros a través de la siguiente dirección:



https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032499034&Culture=es-ES



En resumen, se trata de un evento que no deberíais perderos si queréis construir aplicaciones y componentes ASP.NET mejor estructurados, flexibles, desacoplados, muy mantenibles y fáciles de probar usando pruebas unitarias.



Esperamos veros por allí ;-)



Publicado en Variable not found.



» Leer más, comentarios, etc...

Joan Llenas at garnet.io :: Thoughts on software development

Parsley Task Commands

Diciembre 18th, 2011 - [Enlace local]

Parsley permite crear Commands que devuelven cualquier cosa. Por defecto se soporta void, AsyncToken y Task, siendo éste último tipo de datos el menos popular y desconocido. Provablemente porque no hay documentación al respecto, solo una mención de la posibilidad de hacerlo.
A continuación una explicación y un pequeño ejemplo de cómo crear un DynamicCommand que devuelve y controla el transcurso de un Task.

La primera clave para que la funcionalidad llegue a procesarse es inicializar el contexto con soporte de TaskCommands.

PLAIN TEXT
MXML:
  1. >
  2.     >
  3.         />
  4.         type="{ Context }"/>
  5.     >
  6. >

La segunda es obviamente crear un Command cuyo método execute() devuelva Task.
Y la tercera que el método de retorno tenga el primer argumento de tipo Task, ya que ésto es lo que el procesador de TaskCommands devuelve.

PLAIN TEXT
Actionscript:
  1. package {
  2.     import org.spicefactory.lib.task.Task;
  3.     public class MyTaskCommand
  4.     {
  5.         public function execute(msg:MyMessage):Task
  6.         {
  7.             var myTask:Task = new MyTask();
  8.             return myTask;
  9.         }
  10.  
  11.         public function result(tsk:Task, msg:MyTask):void
  12.         {
  13.         }
  14.     }
  15. }

En el ejemplo que muestro a continuación se puede ver cómo implementar un DynamicCommand que realiza una operación de suma con un número indeterminado de operandos. La clave es utilizar un SequentialTaskGroup dentro de un Command que al completarse permite conocer el resultado gracias a la integración del Command con el Task.

» Leer más, comentarios, etc...

Koalite's blog

AOP con Castle Windsor: IInterceptor

Diciembre 18th, 2011 - [Enlace local]

La Programación Orientada a Aspectos (AOP) es un paradigma de programación que trata de incrementar la modularidad de las aplicaciones aislando aquellos aspectos que afectan a muchas partes de la aplicación sin ser resposabilidad expresa de ninguna de ellas (cross-cutting concerns). Normalmente se usa asociada a OOP y permite que la responsabilidad de las clases quede mucho más definida.

Un ejemplo sencillo sería generar un traza para instrumentar la aplicación y saber qué metodos se están invocando. Si hacemos eso manualmente tendríamos algo así:

public class Calculator : ICalculator
{
    public int Sum(int a, int b)
    {
        log.Write("Enter Sum()");
        var result = a + b;
        log.Write("Exit Sum()");
        return result;
    }
}

Esta implementación tiene dos problemas fundamentales:

Con AOP podemos definir un aspecto y aplicárselo a los métodos que sea necesario para que se escriba la información en log. De esta forma evitamos contaminar todas las clases con la implementación del aspecto.

Seguramente el framework más utilizado y más completo en C# para implementar AOP sea PostSharp, pero si estás utilizando Castle Windsor como contenedor de inversión de control, puedes aprovecharlo para usar ciertas técnicas de AOP.

Crear un interceptor

Para utilizar AOP con Castle Windsor existe una herramienta muy potente: los interceptores.

Un interceptor es una clase que implementa el interface IInterceptor y que nos permite interceptar las llamadas a los métodos de una clase, pudiendo actuar antes o después de la invocación al método. Para hacer esto, Castle Windsor se apoya en otro proyecto de Castle, Dynamic Proxy, que permite generar “al vuelo” proxies usando generación ligera de código (LCG).

En realidad, un interceptor no es más que una forma de implementar un patrón clásico: el patrón decorador. La diferencia es que usando interceptores podemos generar dinámicamente los decoradores, sin necesidad de declararlos previamente.

Para crear un interceptor, sólo necesitamos implementar el interface IInterceptor. Sin embargo, Castle nos ofrece una clase base StandardInterceptor, que a través de un method template nos ofrece los puntos de enganche apropiados para facilitarnos las cosas.

Usando el ejemplo anterior de la traza, tendríamos un interceptor así:

public class TraceInterceptor : StandardInterceptor
{
   private readonly ITraceWriter writer;

   public TraceInterceptor(ITraceWriter writer)
   {
      this.writer = writer;
   }

   protected override void PreProceed(IInvocation invocation)
   {
       writer.Write("Enter: {0}", invocation.Method.Name);
   }

   protected override void PostProceed(IInvocation invocation)
   {
       writer.Write("Exit: {0}", invocation.Method.Name);
   }
}

El objeto IInvocation contiene toda la información del método que estamos interceptando, incluyendo el propio método, los valores de los argumentos que está recibiendo y, tras la invocación, el valor de retorno. En este ejemplo únicamente estamos añadiendo a la traza el nombre del método, pero sería muy sencillo modificarlo para añadir el resto de la información.

Configurando el interceptor

Al principio del post decía que lo bueno de la AOP es que permitía implementar los cross-cutting concerns de forma independiente y luego aplicarlos a las clases que quisiéramos. Esto en Castle Windsor se realiza mediante la configuración de los componentes que registramos en el contenedor.

Lo primero que debemos hacer es registrar en el contenedor el tipo del propio interceptor, ya que cuando Windsor vaya a crear un interceptor lo resolverá del contenedor, cosa que nos permite además añadir al interceptor dependencias sobre otros servicios registrados en el contenedor, como en este caso que depende de ITraceWriter.

var container = new WindsorContainer();
container.Register(Component.For());

Al registrar los componentes que queremos interceptar, debemos indicar qué interceptores queremos aplicarles:

container.Register(Component.For()
                            .ImplementedBy()
                            .Interceptors(new InterceptorReference(typeof (TraceInterceptor)))
                            .Anywhere);

Aunque en el ejemplo anterior lo estamos haciendo para un componente individual (ICalculator), podemos aplicar cualquier convención usando container.Register(AllTypes.FromAssembly...) para configurar el interceptor en todos los componentes que queramos.

Una cosa a tener en cuenta es que al configurar el interceptor podemos elegir el orden en que se va a ejecutar dentro de la cadena de inteceptores que hallamos definido. Usando el fluent interface podemos usar las propiedades AnywereFirst o Last para añadir el interceptor en cualquier parte, al principio o al final de la cadena, respectivamente.

Decidiendo qué métodos interceptar

La forma que acabamos de ver de configurar un interceptor lo hace de tal forma que todos los métodos en son interceptados. Hay ocasiones en que esto no es deseable y existen para ello varias soluciones.

La solución más directa sería poner un if al principio de nuestro código en el interceptor para decidir, en función del nombre del método, si queremos ejecutar la lógica de intercepción o no. Lo malo de esta solución es que ensucia el código del interceptor y acopla la decisión de si hay que interceptar o no a la intercepción como tal.

Windsor nos permite hacer esto de una forma mucho más limpia y efectiva, separando la decisión de los métodos a interceptar de la implementación del interceptor. Para ello debemos implementar el interface IProxyGenerationHook. Este interface nos permite, entre otras cosas, los métodos interceptados:

public class MethodSelectorProxyGenerationHook :IProxyGenerationHook
{
    private readonly string[] methodsToIntercept;

    public MethodSelectorProxyGenerationHook(params string[] methodsToIntercept)
    {
        this.methodsToIntercept = methodsToIntercept;
    }

    public void MethodsInspected()
    {
    }

    public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo)
    {
    }

    public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
    {
        return methodsToIntercept.Contains(methodInfo.Name);
    }
}

En este ejemplo sencillo, indicamos en el constructor los nombres de los métodos que deben ser interceptados y luego, en el método ShouldInterceptMethod, decimos que sólo debemos interceptar un método si está dentro de la lista de métodos a interceptar. En un caso más real, podríamos basarnos en un atributo, un espacio de nombres, un valor de retorno o cualquier otra convención para decidir si el método ha de ser interceptado o no.

Este patrón de separar la decisión de la acción es algo muy recomendable y, por suerte, muy frecuente en todo el código de Castle. Permite una flexibilidad enorme y a la vez genera un código muy claro.

Limitaciones

Como dije antes, los interceptores se aplican usando un proxy generado dinámicamente. Esta generación tiene un impacto la primera vez que se genera el interceptor. Afortunadamente DynamicProxy, el encargado de generar los proxies, tiene un sistema de cache que funciona muy bien y después de generar el proxy para una clase por primera vez, el resto de las veces no hay penalización al rendimiento. De todas formas, como en todos los temas de rendimiento, lo mejor es medir qué impacto tiene en la aplicación antes de empezar a optimizar nada.

Otras librerías de AOP como PostSharp no tienen este problema porque inyectan los aspectos de forma estática en una fase post-compilación usando técnicas de IL weaving que modifican directamente el assembly generado añadiendo las instrucciones IL necesarias.

Además, debe tenerse en cuenta que sólo se interceptan los métodos que pertecenen al interface con el que hemos registrado el componente. Castle genera un proxy que implementa el interface y redirige las llamadas a la implementación que hemos registrado después de pasar por el interceptor. Eso quiere decir que el resto de los métodos de la implementación no serán interceptados. No debería ser problema porque el interface es el contrato externo del servicio y, por tanto, el punto de entrada a cualquier funcionalidad expuesta.

Conclusiones

El ejemplo que hemos visto es seguramente de los más típicos, pero el uso de interceptores para implementar AOP permite hacer cosas realmente interesantes:

El código completo del ejemplo lo podéis encontrar en mi cuenta de github.

Compartir enlace:
Facebook Twitter Email

Posts relacionados:

  1. Aplicaciones modulares con Castle Windsor: IHandlerSelector
  2. Liberado Castle Windsor 3.0
  3. Configurar decoradores en Castle Windsor

» Leer más, comentarios, etc...

El blog de pico.dev

Arte usando texto ASCII con FIGlet

Diciembre 17th, 2011 - [Enlace local]

Seguramente hayas visto en algunos sitios una figura o texto formado por caracteres ASCII, probablemente no hayan sido creadas a mano con la inspiración de un artista, hay herramientas incluso usables desde la web que permiten generarlas. FIGlet es una de ellas que permite crear una figura ASCII a partir de un texto. Su instalción en Arch Linux es tan simple como instalar el paquete figlet con:



$ yaourt -S figlet


En la propia página de figlet podemos encontrar enlaces a varios conjuntos de fuentes a aplicar al texto que queramos generar. También podemos ver algunos ejemplos.



FIGlet tiene más opciones pero la más habitual tal vez sea indicar la fuente a usar y el mensaje del que queremos su representación en arte ASCII.



$ figlet -w 200 "El blog de pico.dev"

_____ _ _ _ _ _ _

| ____| | | |__ | | ___ __ _ __| | ___ _ __ (_) ___ ___ __| | _____ __

| _| | | | '_ \| |/ _ \ / _` | / _` |/ _ \ | '_ \| |/ __/ _ \ / _` |/ _ \ \ / /

| |___| | | |_) | | (_) | (_| | | (_| | __/ | |_) | | (_| (_) | (_| | __/\ V /

|_____|_| |_.__/|_|\___/ \__, | \__,_|\___| | .__/|_|\___\___(_)__,_|\___| \_/

|___/ |_|



$ figlet -f letters.flf -w 200 "El blog de pico.dev"



EEEEEEE lll bb lll dd iii dd

EE lll bb lll oooo gggggg dd eee pp pp cccc oooo dd eee vv vv

EEEEE lll bbbbbb lll oo oo gg gg dddddd ee e ppp pp iii cc oo oo dddddd ee e vv vv

EE lll bb bb lll oo oo ggggggg dd dd eeeee pppppp iii cc oo oo ... dd dd eeeee vvv

EEEEEEE lll bbbbbb lll oooo gg dddddd eeeee pp iii ccccc oooo ... dddddd eeeee v

ggggg pp



Los textos ASCII generados por FIGlet nos pueden ser de utilidad en los sitios en los que solo podamos usar caracteres de texto como en correos electrónicos que no lleven formato html o en los archivos de log de una aplicación.



Referencia:

http://www.figlet.org/

http://patorjk.com/software/taag/

http://www.network-science.de/ascii/

» Leer más, comentarios, etc...

Koalite's blog

Liberado Castle Windsor 3.0

Diciembre 17th, 2011 - [Enlace local]

Se acaba de liberar la versión 3.0 de Castle Windsor, cuya lista de cambios podéis encontrar en el wiki oficial.

En este blog que he hablado varias veces de Castle Windsor. Para mi no sólo es el mejor contenedor de inversión de control para .NET, sino que me parece una de las librerías open source para .NET mejor desarrolladas, con un código muy elegante, fácil de entender y, seguramente por ello, de extender.

Si nunca lo has probado, es un momento idóneo para descargarlo y descubrir todo lo que puede aportar a tus aplicaciones.

Compartir enlace:
Facebook Twitter Email

Posts relacionados:

  1. Configurar decoradores en Castle Windsor
  2. Aplicaciones modulares con Castle Windsor: IHandlerSelector

» Leer más, comentarios, etc...

Monocaffe

Jongo Beta 0.1

Diciembre 16th, 2011 - [Enlace local]

Last night I uploaded the first version of Jongo. This is a beta version and all of the projected functionality is provided.







In future versions support for more RDBMS will be added, like Microsoft SQL Server and Sybase using the jTDS JDBC Driver. Also support for PostgreSQL and SQLite is projected.



A couple of screenshots:







This is the administration console, from where you can control the tables Jongo will provide access to. It's completely made with jQuery and is a good example of how to work with jQuery.Ajax() and Jongo.











The cidb application is a demonstration of how to use ExtJS rest stores without any server side coding.



If you find Jongo useful please leave your feedback. Find any bugs, errors or have a cool idea? Open a ticket!

» Leer más, comentarios, etc...

Fetishcode

LOV en Tabla con autoSuggestBehavior

Diciembre 16th, 2011 - [Enlace local]

A

» Leer más, comentarios, etc...

Picando Código

Fundación Ciudadano Inteligente – Quiénes son, y por qué Google les donó 1/4 millón de dólares

Diciembre 15th, 2011 - [Enlace local]

Una excelente noticia que comparto con ustedes. La Fundación Ciudadano Inteligente ha recibido una donación de U$S 250.000 por parte de Google. ¿Qué es esto de Fundación? Entre varias cosas, fueron la organización responsable del concurso Desarrollando América Latina del cual ya les he hablado bastante.

Su logro de haber unido a los desarrolladores de 6 países es parte de su actividad de potenciar, construír y visibilizar aplicaciones tecnológicas mediante las cuales se congreguen instancias e iniciativas de participación ciudadana y accountability social, y facilitar el acceso a la información pública, al entenderlo como un derecho ciudadano.

Fundación Ciudadano Inteligente

Fundación Ciudadano Inteligente

Pero, ¿qué es exactamente Ciudadano Inteligente?:

Somos una organización social sin fines de lucro con sede en Santiago de Chile, promotores de la participación activa y responsable de la ciudadanía por la vía de nuevas tecnologías y el acceso a la información. Nuestro objetivo es reducir las asimetrías de información que separan al ciudadano de la política, el mercado y demás espacios sociales, como condición necesaria para la integral participación de éste.

Nuestra Fundación concibe a las nuevas tecnologías como herramientas fundamentales para recopilar, organizar, ilustrar y difundir información a través de las redes sociales, como también para canalizar espacios concretos de acción y accountability ciudadano a través de la web.

Como fundación no adscribimos a ninguna tendencia política, lo que no significa que nuestros miembros y voluntarios sean “a-políticos”. Muy por el contrario, nos interesa profundamente la política y es por ello que nos apasiona promover políticas públicas de calidad e iniciativas que transversalmente mejoren el desarrollo democrático.

Si como yo, suscriben con la idea, estarán contentos de conocer esta noticia. Según me comentaron desde la Fundación, será el impulso para internacionalizar FCI sobre todo después del éxito de Desarrollando América Latina. ¿Tendremos pronto una sede de Ciudadano Inteligente por país?

Proyectos Ciudadano Inteligente

Proyectos Ciudadano Inteligente

Les dejo con el comunicado de prensa:

Fundación Ciudadano Inteligente: recibe donación de Google.org

La Fundación Ciudadano Inteligente obtuvo US$ 250.000 de Google.org charitable giving initiatives para desarrollar sus aplicaciones en diversos países de América Latina.

Santiago (14 de diciembre de 2011)
Google distinguió uno de los proyectos que desarrolla la ONG chilena, Fundación Ciudadano Inteligente (FCI) y realizó una importante donación con el objetivo de que ésta siga creciendo en sus diversas aplicaciones tecnológicas a lo largo de América Latina.

De esta forma, la compañía que ha desarrollado uno de los motores de búsqueda de Internet más exitosos y poderosos de la red, decidió donar US$250.000 a esta ONG sudamericana, para que la fundación siga en su tarea de reducir las asimetrías de información a través de tres pilares básicos como son: el accountability, la participación ciudadana y la transparencia.

Estos fondos serán utilizados por la Fundación Ciudadano Inteligente para internacionalizar sus aplicaciones tecnológicas a lo largo de América Latina, así como consolidar una de sus recientes herramientas de Open Data (datos abiertos) llamada Criik.com, que es un receptorio de datos públicos que permite a desarrolladores, programadores y diseñadores crear distinto tipo de aplicaciones.

La Fundación Ciudadano Inteligente (FCI) tiene entre sus objetivos construir una comunidad potente en América Latina, un continente donde más del 60% de la población considera que la desigualdad es el principal problema social. Por eso el acceso a los datos públicos y la creación de un laboratorio de desarrollo latinoamericano de aplicaciones web que fomenten la transparencia se hace absolutamente vital para reducir esta desigualdad.

Durante el último período del año 2011, Google.org anunció un plan de donaciones equivalentes a US$ 40 millones de dólares. La última entrega de fondos fue para esta importante ONG que ha ido ganando terreno a nivel nacional y que tiene el sueño y desafío de conquistar América Latina.

Juan José Soto, el gerente de la Fundación Ciudadano Inteligente, comenta que “es un orgullo la confianza que Google.org ha depositado en nuestra ONG. Además la motivación de llegar con las aplicaciones que hemos creado a otros países del continente es fundamental para la internacionalización de FCI.

» Leer más, comentarios, etc...

Koalite's blog

La otra podredumbre del software

Diciembre 14th, 2011 - [Enlace local]

Después de leer este post sobre la podredumbre del software, no he podido evitar pensar en el que, para mi, es uno de los mayores problemas a la hora de desarrollar software, especialmente si se trata de productos estándar.

Cuando un cliente o uno de nuestros comerciales quiere añadir algo a una aplicación, generalmente se acerca a mi con preguntas como ¿se puede hacer que…? ¿costaría mucho si…? ¿cuánto se tardaría en…?

Mal. Antes de añadir una funcionalidad, la primera pregunta que hay que responder es ¿debería la aplicación hacer…? El problema de las preguntas anteriores es que asumen que la respuesta a ésta última es afirmativa, pero eso no siempre es así.

Lo malo es que el software lo aguanta (casi) todo. En comparación con el Mundo Real™, donde existen unas leyes muy rígidas que marcan lo que se puede hacer y lo que no, en el mundo del desarrollo de software esas leyes son mucho más flexibles, especialmente para la gente que no comprende realmente lo que es desarrollar software.

Pollo sin cabeza

¿A dónde quería yo llegar?

El desarrollo de software es un proceso que tiene como objetivo producir algo. Un producto. Es importante tener claro el producto que queremos conseguir con un desarrollo de software, pero muchas veces la supuesta flexibilidad del desarrollo como proceso hace que el objetivo inicial se diluya, se transforme y, finalmente, se pierda.

No estoy hablando de esculpir unas especificaciones en piedra y ceñirse a ellas. A estas alturas el que más y el que menos conoce las metodologías ágiles y, la mayoría de nosotros, las apoyamos. Nos preparamos para el cambio, lo abrazamos, y todo eso…

Sin embargo, una cosa es estar preparado para el cambio y otra muy distinta es correr como pollos sin cabeza, cambiando continuamente de rumbo sin un objetivo fijo.

Hay productos que parece que evolucionan así:

Cronología de un proyecto

Versión 1.0: Hemos preparado un producto llamado Paella que va a romper el mercado.

Un cliente dice que la competencia le ofrece Macarrones con Chorizo, ¿cómo es posible que nuestra paella no lleve chorizo?

Versión 2.0: Paella con chorizo.

El product manager ha decidido que el futuro son los iPhone y la movilidad. Quiere una paella que se pueda comer en cualquier parte.

Versión 3.0: Paella Mobile con Chorizo.

Sandwich de Paella

Paella Mobile con Chorizo y Gambas

Seguro que muchos de vosotros habéis estado involucrados en proyectos así. Proyectos en los que cualquier cosa que se le ocurriese a un cliente potencial acababa automáticamente en el backlog del producto (y con prioridad alta), sin tener en cuenta si era una buena idea, o al menos si era compatible y consecuente con lo que intentaba conseguir.

Muchas veces los proyectos acaban dirigidos por gente que está demasiado cerca del cliente y con una presión muy elevada por parte de éste, lo que provoca que no sea fácil mantener la cabeza fría y la visión a medio/largo plazo.

En esos casos, cada nuevo cliente se convierte en una nueva funcionalidad apilada sin ningún criterio sobre la aplicación, provocando contradicciones, disminuyendo la usabilidad y dañando el producto en su conjunto.

Llegas a la situación en que el cliente dirige tu desarrollo y acabas por diseñar algo al más puro estilo Homer Simpson:

Coche diseñado por Homer Simpson

Esto es lo que vas a conseguir si tu cliente diseña tu aplicación

No siempre está en nuestras manos decidir lo que va a pasar con lo que estamos desarrollando. Debemos trabajar para que el software sea mantenible, robusto, usable, etc., pero también podemos aportar nuestra experiencia e intentar que el producto en el que estamos trabajando siga teniendo sentido.

Compartir enlace:
Facebook Twitter Email

No hay posts relacionados.

» Leer más, comentarios, etc...

Picando Código

The Humble Indie Bundle #4

Diciembre 14th, 2011 - [Enlace local]

Y una vez más nos encontramos ante un nuevo Humble Indie Bundle original. La historia ha sido más o menos así por el momento: La primera edición del Humble Indie Bundle (mayo de 2010) tuvo un éxito importante, por lo que liberaron el código de los juegos. En diciembre de ese año hubo un Humble Indie Bundle 2, y en julio de 2011 se lanzó el Humble Indie Bundle 3.

Además, este año han habido algunas ediciones de estudios específicos de videojuegos:

Pero una vez más volvió el Humble Indie Bundle original.

Humble Indie Bundle 4

Humble Indie Bundle 4

La iniciativa sigue con sus reglas:

En esta ocasión contamos con 5 juegos y 2 extra si superamos el precio promedio (al momento de escribir este post U$S 5.27). Los juegos son: Shank, Super Meat Boy, NightSky, Jamestown, Bit.Trip Runner y los dos extra Gratuitous Space Battles y Cave Story+. Los 7 juegos están disponibles para GNU/Linux por primera vez a través de este paquete :D

Juegos Humble Indie Bundle 4

Juegos Humble Indie Bundle 4

No habiendo jugado los 7 aún, me arriesgo a afirmar que este es el mejor Humble Bundle hasta el momento. Ya conocía Shank de antes, lo juegué en Playstation 3 y es muy entretenido. Ahora estoy descargando los 2GB del bin por Torrent (al momento de estar publicada esta entrada, seguramente ya haya descargado).

Super Meat Boy

Super Meat Boy

Super Meat Boy es un juego de plataformas bastante popular en el mundillo de los videojuegos independientes. Si bien me lo habían recomendado, al no estar disponible para GNU/Linux, no lo había podido probar. Los desarrolladores comentaron varias veces que un port estaría en camino, y finalmente ve la luz ahora. Hasta ahora solo había podido escuchar el soundtrack (también muy bueno), por el Indie Game Music Bundle.

Fue el primero que descargué y probé, y funcionó perfecto. Tengo un gamepad de Xbox 360 (en el mundo del hardware, Microsoft hace algunas cosas bien, a diferencia del software…), lo conecté, y el juego lo reconoció instantáneamente. ¡Es sumamente divertido! Pasé el primer mundo en cuestión de minutos. Y resulta muy catártico ver ese pequeño personaje destruído contra una sierra o similar cada tanto…

Jamestown

Jamestown

Jamestown me sorprendió gratamente. Se trata de un shoot’em up con scroll vertical al estilo 1942 de Capcom, con gráficos pixelados que traen recuerdos en 16 bits. También lo jugué con el gamepad, creo que la única forma de realmente disfrutar de juegos de este estilo.

La ambientación es una onda Steampunk, nos encontramos en una colonia británica en Marte en el siglo 17, con toda una historia que nos introduce a la acción. Pueden hacer como yo, saltearla e ir directo a los tiros (tras un corto pero necesario tutorial). El juego es ultra entretenido, pero incluye además modo cooperativo de hasta 4 jugadores, lo que debe multiplicar la diversión, queda pendiente por probar.

Bit.Trip Runner

Bit.Trip Runner

El otro juego que probé hasta el momento fue Bit.Trip Runner. Lo primero que llama la atención son los gráficos -muy coloridos, 3D con vóxeles (inmediatamente me hizo acordar a Voxatron) pero que se juega en 2D- seguidos de la música. Cuenta con una banda sonora de Chiptunes, con la excelente banda Anamanaguchi como invitados.

No avancé mucho en el juego, pero lo poco que jugué parece bastante novedoso el sistema, generando con nuestro progreso el ritmo de la música del nivel. Es entretenido, y también ideal para jugar con el gamepad.

El juego Cave Story+ lo había probado en mi PC, ya que está disponible en los repositorios de AUR de ArchLinux como doukutsu, y no me ha convencido mucho hasta el momento, a lo mejor debería jugarlo más. Me quedan probar NightSky y Gratuitous Space Battles.

Como comentario adicional, agregar que este bundle fue el que más se vendió hasta ahora en menor tiempo. En las primeras 4 horas alcanzó 100.000 ventas y más de U$S 500.000. Personalmente me gustó mucho el bundle, conociendo Super Meat Boy y Shank, también fue el que más pagué (me hubiera sentido culpable pagando menos). Así que al haberlo comprado en los primeros momentos de la promoción, estuve unos pocos segundos en la lista de los “Top contributors”:

picandocodigo en los Humble Bundles...

picandocodigo en los Humble Bundles...

A la hora de escribir esta entrada, llevan recaudados unos U$S 800.000, por lo que seguramente se haya superado el millón de dólares para cuando lean esto. El precio promedio sigue alrededor de los 5 dólares, y se mantiene la tendencia de todos los bundles anteriores:
Los usuarios de GNU/Linux pagamos el doble que los usuarios Windows y un poco más que los usuarios Mac.
Desde mi punto de vista, esto es un paso importante para nuestra plataforma. Si estudios independientes pueden hacer sus ports a nuestro sistema, que los estudios grandes no lo hagan es una cuestión de intereses, no de falta de recursos.

De todas formas, el hecho de que este bundle haya hecho debutar en GNU/Linux 7 juegos nuevos es una gran noticia y un gran paso adelante como se viene haciendo con cada edición. Los que dicen que no se puede jugar en Linux, tendrían que ver la cada vez más grande lista de juegos instalados en mi ArchLinux. Ahora necesito un fin de semana entero para dedicarles…

Es un buen tiempo para los videojuegos independientes, particularmente un excelente momento para los videojuegos en GNU/Linux :)

» Leer más, comentarios, etc...

Variable not found

ASP.NET MVC: establecer el foco en un control al cargar la página

Diciembre 14th, 2011 - [Enlace local]

ASP.NET MVCUno de los aspectos más criticados por los desarrolladores cuando comienzan a trabajar con ASP.NET MVC es el hecho de tener que volver a resolver problemas que estaban ya más que solucionados en Webforms.



Y uno de estos casos es un detallito muy simple pero útil: establecer el foco de edición en un control concreto al cargar una página. En Webforms era suficiente con asignar al atributo defaultFocus del tag <form> el nombre del control que nos interesara, y ya lo teníamos solucionado; ASP.NET MVC no trae ninguna solución “de serie” para conseguirlo, aunque, como veremos en este post, no es mucho más complicado que la alternativa Webforms una vez hemos preparado la infraestructura necesaria.



En líneas generales, la solución consiste en utilizar un pequeño script que, una vez cargada la página, mueva el foco hacia el control que nos interese. Por ejemplo, si quisiéramos que el campo con identificador “Nombre” obtenga el foco automáticamente, podríamos utilizar jQuery de la siguiente forma:

<script type="text/javascript">
    $(function () {
        $("#Nombre").focus();
    });
</script>
Aunque eficaz, es una solución demasiado trabajosa e introduce una dependencia en el código, difícilmente manejable, hacia el nombre del control. Si quisiéramos introducir este código en múltiples puntos de nuestra aplicación tendríamos que copiar y pegar en cada vista, y sustituir el id del control apropiado en cada caso, lo cual es bastante incómodo.



¿No podríamos mejorar esto un poco?

El helper SetFocusTo()

Una posible solución, realmente rápida de implementar, sería crear un helper personalizado, al que llamaremos SetFocusTo(),  que genere el código por nosotros partiendo únicamente de la información de la propiedad a editar.



Y para evitar la dependencia hacia el nombre de la propiedad y hacerlo más flexible, incluso podríamos crear la versión fuertemente tipada del mismo, de forma que podamos utilizarlo de cualquiera de las siguientes formas:

// Usando el nombre de la propiedad:
@Html.SetFocusTo("Nombre")

// Usando la versión fuertemente tipada:
@Html.SetFocusTo(model=>model.Nombre)
El código del helper es el siguiente:

public static class HtmlHelpers
{
    public static MvcHtmlString SetFocusTo<TModel, TProperty>(
                    this HtmlHelper<TModel> html,
                    Expression<Func<TModel, TProperty>> expression)
    {
        var prop = ExpressionHelper.GetExpressionText(expression);
        return html.setFocusTo(prop);
    }

    public static MvcHtmlString SetFocusTo(this HtmlHelper html, 
                                           string propertyName)
    {
        var prop = ExpressionHelper.GetExpressionText(propertyName);
        return html.setFocusTo(prop);
    }

    private static MvcHtmlString setFocusTo(this HtmlHelper html, 
                                            string property)
    {
        string id = html.ViewData.TemplateInfo.GetFullHtmlFieldId(property);
        var script = "<script type='text/javascript'>" +
                        "$(function() {" +
                            "$('#" + id + "').focus();" +
                        "});" +
                        "</script>";
        return MvcHtmlString.Create(script);
    }

}
Recordad que para que estos helpers estén visible en las vistas y podáis usarlos normalmente, debéis incluir el espacio de nombres en el que están definidos bien sea añadiendo una directiva @using en la vista, o bien en la sección <namespaces> del archivo web.config que encontraréis en la carpeta /Views (o en la del área correspondiente).



¡Y eso es todo! De esta forma tan simple, ya volvemos a disponer de la posibilidad de establecer el foco por defecto sobre un control de forma muy rápida, compacta, y cómoda de utilizar.



Publicado en: Variable not found.



» Leer más, comentarios, etc...

Buayacorp

WordPress 3.3 “Sonny”

Diciembre 13th, 2011 - [Enlace local]

Una nueva versión acaba de salir con bastantes mejoras a nivel de la interfaz de usuario y también con respecto al rendimiento en el tema de permalinks, sobre todo para sitios que usan URLs del tipo %postname%.

» Leer más, comentarios, etc...

Información legal y técnica