My kemenworld…

To mock or not to mock…

TypeForwardedToAttribute

Posted by kementeus en octubre 23, 2006

Estudiando un poco sobre atributos en la .Net Framework me topo con alguien nuevo en el mundo de los atributos, se trata de TypeForwardedToAttribute. Buscando en la ayuda de la MSDN no surte mucho el resolver la duda de como usarlo, y luego de buscar otro poco en internet dentro de un par de blogs tampoco resolvió mis dudas.

Luego de un rato comprendí que para entender el uso de TypeForwardedToAttribute debía entender el problema que resolvía. Imaginemonos el caso hipotético de crear una libreria de sistema que alguien mas trabajará.

public class FooOne 
{ 
	public static void SayHello() 
	{ 
		Console.WriteLine("[lib1] Hola mundo"); 
	} 
} 

public class FooTwo 
{ 
	public static void SayGoodBye() 
	{ 
		Console.WriteLine("[lib1] Adios mundo"); 
	} 
}

Como recordaremos podriamos compilar este ejemplo usando el siguiente codigo:

csc /t:library foo.cs

Esto me generara el lindo foo.dll que esperaba tener. En base a esta libreria decidí ahora crear un ejecutable que me saludara y me dijera adios luego, esto es fácil simplemente escribo un par de líneas:

public class Test 
{ 
	public static void Main() 
	{ 
		FooOne.SayHello(); 
		FooTwo.SayGoodBye(); 
	} 
}

Bien, ahora copiamos foo.dll al directorio donde esta test.cs y compilamos el código, como hacemos referencia a clases dentro de una libreria simplemente le indicamos esto al compilador:

csc /r:foo.dll test.cs

Como es de esperar probamos nuestro código y todo funciona como esperabamos, simplemente ejecutamos test.exe y nos devuelve:

Hola mundo 
Adios mundo

Bueno, resulta que por razones estéticas durante el refactoring de nuestra aplicación decidimos mover la ubicación de nuestra clase para decir adios, así quedamos con el siguiente código:

// En foo.dll 
public class FooOne 
{ 
	public static void SayHello() 
	{ 
		Console.WriteLine("[lib1] Hola mundo"); 
	} 
} 

// En newfoo.dll 
public class FooTwo 
{ 
	public static void SayGoodBye() 
	{ 
		Console.WriteLine("[lib2] Adios mundo"); 
	} 
}

Bien, compilamos esto en dos librerias separadas, foo.dll y newfoo.dll :

csc /t:library foo.cs 
csc /t:library newfoo.cs

Como cambiamos todo y tenemos dos librerias copiemos foo.dll y newfoo.dll al directorio donde esta nuestro amigo test.exe, cuando tratamos de correr test.exe nos dice q no encuentra FooTwo, es lógico, lo movimos a newfoo.dll pero como test.exe no sabe nada de la existencia de FooTwo en newfoo.dll no lo encontrará y fallará la ejecución.

Anteriormente tendriamos que recompilar test.exe y agregar las referencias a foo.dll y newfoo.dll, algo que no queremos que el autor de test.exe haga (por alguna razón específica, aún realmente no se me ocurre ninguna :P), para eso usamos a nuestro amigo TypeForwardedToAttribute, intentemoslo ahora, abramos foo.cs:

public class FooOne 
{ 
	public static void SayHello() 
	{ 
		Console.WriteLine("[lib1] Hola mundo"); 
	} 
} 
[assembly: System.Runtine.CompilerServices.TypeForwardedTo(typeof(FooTwo))]

Ahora recompilemos solamente foo.dll:

csc /t:library /r:newfoo.dll foo.cs

Y ahora movamos la nueva foo.dll al directorio de test.exe, probamos y voila! funcionó!

Bueno, todo esto es solamente para explicar que de esta manera podemos ahorrarle al creador de test.exe tener que recompilar a test.cs, creo que esto facilita mucho el versioning de las librerias, una prueba mas de la orientación de la .Net framework al desarrollo de componentes.

Antes de finalizar quiero esclarecer un par de puntos:

  • No intenten esto en Mono, TypeForwardedTo es propio de la .Net Framework 2.0 y recuerden que Mono esta orientado hasta ahora al fiel cumplimiento de la 1.1
  • Cuando quieran modificar o rehacer test.cs al momento de compilar fallará, bueno, esto es obvio, el atributo esta hecho para no afectar los assemblies ya modificados, una vez que queramos recompilar test.cs debemos ahora agregar la referencia a newfoo.dll
  • Si usan un namespace el atributo debe estar fuera de las declaraciones del namespace. Un buen lugar para colocar los atributos assembly es un archivo llamado AssemblyInfo.cs

Espero que esto les haya ayudado en algo, los veo en mi próximo post.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

 
A %d blogueros les gusta esto: