Sunday, June 11, 2006

TypeForwardedToAttribute

En la entrada anterior, analicé un poco acerca del tema de Generics, ahora vamos con una nueva característica ofrecida por el Framework 2.0.

El atributo TypeForwardedToAttribute, permite básicamente poder mover los tipos definidos en nuestros assemblies, a nuevos assemblies, y que las aplicaciones clientes, simplemente sean redirecionadas a las nuevas localizaciones de los tipos que esten usando del assemblie, del cual han sido movidos estos tipos. Permitiendo de este modo, simplemente compilar los assemblies pero no las aplicaciones clientes.

Veamos esto en marcha, con un ejemplo muy sencillo.

Nuestro assemblie que llamaré "Original" tiene un tipo llamado Ejemplo:

using System;

namespace Probando
{
class Ejemplo
{
static Ejemplo()
{
Console.WriteLine("Estoy en el ensamblado original.");
}
}
}

para compilar el código anterior simplemente copienlo en su NotePad, nombren el archivo como original.cs y usando el Command Promp de VS.NET, escribimos el siguiente comando:

css /t:library original.cs

Bien con esto ya tenemos el ensamblado "original" con una clase llamada Ejemplo. Recuerden /t:library, le indica al compilador que el resultado va a ser una libreria de clases, no una aplicación ejecutable, ya que nuestro primer ensamblado no contendrá ningún método main().

Ahora creemeos un pequeño cliente que referencie el ensamblado y utilice su clase:

using System;
using Original;

namespace Aplicacion
{
class Prueba
{
static void Main()
{
Ejemplo obj = new Ejemplo();
}
}
}

Copien el código anterior al bloc de notas y nombren el archivo como prueba.cs.
En este pequeño cliente, se puede apreciar que se está creando una instancia de la clase Ejemplo, definida en el ensamblado "original".
La compilación del código anterior la pueden ejecutar de la siguiente mandera:

csc /r:original.dll prueba.cs

/r le indica al compilador que se está haciendo referencia al ensamblado original.dll, el cual contiene la definición de la clase Ejemplo, que estamos usando en nuestro cliente.


La salida de prueba.exe será: "Estoy en el ensamblado Original."

Supongamos que hemos decidido mover el tipo definido en el ensamblado "original" a otro ensamblado que llamaremos NuevaVersion. Entonces cortamos la definición de la clase Ejemplo del ensamblado "original" y la pegamos en un nueco archivo que llamaremos nuevaversion.cs. Compilamos original.cs como lo habiamos hecho antes c
on lo cual al ejecutar nuestro cliente obtendremos el siguiente error:

prueba.cs(2,7): error CS0246: The type or namespace name 'Original' could not be found (are you missing a using directive or an assembly reference?)

Es obvio lo anterior ya que hemos movido el tipo Ejemplo al nuevo ensamblado que ha quedado así;

using System;
namespace Probando
{
public class Ejemplo
{
public Ejemplo()
{
Console.WriteLine("Estoy en el ensamblado Nueva Versión.");
}
}
}

Copiamos el anterior código en el bloc de notas, y nombramos el archivo como NuevaVersion.cs, y se compila así:

css /t:library nuevaversion.cs

Ahora entonces que debemos hacer, para evitar recompilar la aplicación cliente y que siga funcionando aunque haya sido movido el tipo al nuevo ensamblado?

Agregamos el siguiente atributo, al ensamblado Original, con lo que el código de original.cs queda así:


using System;
using System.Runtime.CompilerServices;

[assembly: TypeForwardedTo(typeof(Probando.Ejemplo))]
namespace Probando
{
}

Primero noten el nuevo NameSpace agregado System.Runtime.CompilerServices; para poder hacer uso del atributo [assembly: TypeForwardedTo(typeof(Probando.Ejemplo))].
Con lo anterior, el cliente seguirá llamando al ensamblado original, pero este internamente redireccionará al ensamblado NuevaVersion para acceder al tipo Ejemplo, que previamente ya habiamos movido a ese nuevo ensamblado.

Con esto el cliente ahora recibirá el mensaje:
"Estoy en el ensamblado Nueva Versión."

Esta es una grandiosa característica, que puede servir mucho para los que se dediquen a crear librerias de clases y necesiten realizar este tipo de actualizaciones, y quieran no tocar nada en las aplicaciones cliente.

1 comment:

Anonymous said...

Y por qué no simplemente se modifica el código de "Original" con lo que tenga "NuevaVersion". Al fin y al cabo lo que estaba en Orignial deja de usarse y hay que recompilarlo de todas formas. Gracias.