Cualquier cosa que valga la pena se hace en equipo

Cualquier cosa que valga la pena se hace en equipo

viernes, 4 de junio de 2010

Programacion Reflexiva . PARTE III

Algo más al respecto

Los assemblies contienen módulos, los módulos contienen tipos y los tipos contienen funciones miembro o métodos.
-
Lo que Reflection provee son objetos que encapsulan a estas unidades (assemblies, módulos y tipos) de modo de crear dinámicamente una instancia de un tipo, ligar ese tipo a un objeto existente u obtener el tipo de un objeto existente.-

De este modo podemos invocar los métodos del tipo y/o acceder a sus campos y propiedades. El uso típico de reflection debería seguir estas reglas:

1. Usar la clase Assembly para definir y cargar assemblies, cargar los módulos que el assembly contiene y que se encuentran en el Manifiesto, ubicar el tipo del assembly en si y crear una instancia del mismo.-

Esto lo podemos hacer con:

Assembly a = Assembly.LoadFrom(args[0]);
O
Assembly a = Assembly.GetExecutingAssembly();

El primer modo es genérico y solo requiere que se indique el assembly. (El paso completo del mismo será obligatorio si no se encuentra en la GAC). El segundo método está restringido a el trabajo con clases que se encuentran en el assembly actual.-

2. Usar el método CreateInstance() para instanciar un objeto de un tipo dado:

Object o = assem.CreateInstance("Ejemplo2", false,
BindingFlags.ExactBinding, null, new Object[] { 2 }, null, null);


· Alternativamente observemos que esto puede hacerse así:

MethodInfo m = assem.GetType("Ejemplo2").GetMethod("MetodoDeEjemplo");
Object ret = m.Invoke(o, new Object[] { 42 });

El método GetType retorna un objeto de la clase MethodInfo.
Observemos que igual que en el caso anterior, el nombre de la clase y el de su metodo, SON LITERALES lo que indica que pdrian ser cargados en tiempo de ejecucion en variables string y la llamada a Assembly.GetType o a Assembly.CreateInstance se podria hacer con datos dinamicos.
Desde ya que esta es la funcion ultima de Reflection.-
Observe de todos modos que debe conocer “algo” del tipo o del metodo de modo de invocar correctamente a los constructores o pasar parametros adecuados a los metodos.-

EJEMPLO II

En este ejemplo haremos una variante que nos llevara a un caso más parecido al que planteamos al principio de esta y que mostramos con un ejemplo en lenguaje C.-
Construiremos 3 proyectos, ambos en la misma solucion solo a los efectos de la simplicidad.
Uno, al que llamaremos biblioteca1, correspondera al armado de una biblioteca donde estan las clases de las que crearemos objetos a los que a accederemos.-
El segundo, al que llamaremos pruebabiblioteca, sera una aplicacin intermedia de ayuda. Esto no es necesario para el proyecto final que es una aplicación que usando reflection hara uso de los metodos de la biblioteca. Pero es una biena idea probar la biblioteca SEPARADAMENTE antes de darle un uso generico. Es por eso que colocamos este proyecto dentro del ejemplo.-
El tercero, que es el que nos importa, sera la aplicación que a traves de Reflection accede a estos objetos y sus metodos en modo dinamico.-

El proyecto biblioteca1

El primer proyecto sera del tipo Class Library y en el colocaremos una clase con dos metodos.-
Luego esta sera nuestra biblioteca armada como Assembly.-
Vamos con el primer proyecto que consiste en armar la biblioteca de la clase que expondra funcionalidad a ser utilizada por el segundo proyecto:
Este es un proyecto Class Library de modo de armar una biblioteca con una clase que exporte sus metodos.-

El codigo que escribiremos para crear tal clase es el que se muestra a continuacion:

using System;
using System.Collections.Generic;
using System.Text;

namespace biblioteca1
{
public class UnaClase
{
public static Boolean SinNumeros(string dato)
{
char []numeros = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
if (dato.LastIndexOfAny(numeros) == -1)
return (true);
else
return (false);
}

public static Boolean SinÑuflos(string dato)
{
char []ñuflos = new char[] { '@', '^', '`', '¨', '~' };
if (dato.LastIndexOfAny(ñuflos) == -1)
return (true);
else
return (false);
}

}
}


Ahora vamos a armar la biblioteca (biblioteca1) como una dll que expondrá la clase UnaClase y sus métodos públicos.-
Esto generara el archivo biblioteca1.dll .-
Revise en la pantalla de salida donde queda generada:

El proyecto PruebaBiblioteca

Ahora vamos a construir el segundo proyecto

Vamos a hacer una aplicación de consola que utilice la biblioteca creada en el proyecto anterior.
Lo hara del modo habitual, es decir sin utilizacion de reflection.
EL codigo C# de este proyecto esta en un solo modulo al que llamaremos Program y es el que se ve a continuacion:

using System;
using System.Collections.Generic;
using System.Text;
using biblioteca1;

namespace PruebaBiblioteca
{
class Program
{
static void Main(string[] args)
{
string dato = "ABCDE";
if (biblioteca1.UnaClase.SinNumeros(dato) == true)
Console.WriteLine("{0}: No tiene numeros");
else
Console.WriteLine("{0}: Tiene numeros");

dato = "AB1C2DE";
if (biblioteca1.UnaClase.SinNumeros(dato) == true)
Console.WriteLine("{0}: No tiene numeros");
else
Console.WriteLine("{0}: Tiene numeros");

dato = "A~CDE";

if (biblioteca1.UnaClase.SinÑuflos(dato) == true)
Console.WriteLine("{0}: No tiene Ñuflos");
else
Console.WriteLine("{0}: Tiene Ñuflos");

}
}
}

No hay comentarios: