Activator, crear objetos a partir de texto

Activator, crear objetos a partir de texto

Hace algunos años, en uno de los primeros articulos que escribí en devjoker - pulsa aqui para ver el artículo original - explicabamos la forma de crear instancias de un objeto a partir de un string con C#, algo que habia implementado con gran exito en proyecto Java anterior.

Para ello definiamos un interfaz, utilizamos el dominio de aplicacion actual para obtener un objeto con AppDomain.CurrentDomain.CreateInstance y posteriomente convertiamos y ejecutamos la interfaz. Muy al estilo del patrón de diseño Factory Method basado en interface,.

Lo que es la ignorancia - por aquellos tiempos andaba aprendiendo esto del .NET -, y es que el framework posee una clase especializa en realizar esta tarea. La clase Activator.

En este ejemplo vamos a hacer otra implementacion del patron de diseños factoria, pero está vez en lugar utilizar un interface vamos a utilizar una clase abstracta. Definimos una clase abstracta ProveedorPadre, y las clase que hereden de esta deben sobreescribir el método HacerAlgo<T> ¡más generico no se puede!

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace ActivatorSample

{

class Program

{

static void Main(string[] args)

{

string typename = "OtroNamespace.Proveedor1";

if (args.Length > 0)

{

typename = args[0];

}

ProcessType( typename);

Console.ReadLine();

}

 

private static void ProcessType(string typename)

{

Type tipo = Type.GetType(typename);

if (typeof(ProveedorPadre).IsAssignableFrom(tipo))

{

ProveedorPadre director =

(ProveedorPadre)Activator.CreateInstance(tipo);

director.HacerAlgo<int>(1);

director.HacerAlgo<string>("parametros");

director.HacerAlgo<DateTime>(DateTime.Now);

}

else {

throw new

InvalidOperationException("No implementa ProveedorPadre");

}

}

}

 

public abstract class ProveedorPadre

{

public abstract void HacerAlgo<T>(T indata);

}

 

}

 

namespace OtroNamespace

{

public class Proveedor1 : ActivatorSample.ProveedorPadre

{

public override void HacerAlgo<T>(T indata)

{

Console.WriteLine(

"Se ha recibido en Proveedor 1 el dato: {0}",indata.ToString());

}

}

 

public class Proveedor2

{

public Proveedor2()

{

//Sencillamente no hereda de ProveedorPadre!

}

}

}

En este ejemplo hemos incluido una segunda clase Proveedor2 que no hereda de nuestra clase abstracta, para controlar el posible error. Si invocamos al programa y enviamos por parametro "OtroNamespace.Proveedor2" obtendremos una excepcion de tipo InvalidOperationException.

La pregunta ahora es inmediata ... ¿que método es mejor y cual debo utilizar? ... pues lo mismo dá porque AppDomain.CurrentDomain.CreateInstance lo que hace internamente es invocar a la clase Activator.

Si analizamos la clase Activator con .NET Reflector podemos observar su implementación:

 

public System.Runtime.Remoting.ObjectHandle

CreateInstance(string assemblyName, string typeName)

{

if (this == null)

{

throw new NullReferenceException();

}

if (assemblyName == null)

{

throw new ArgumentNullException("assemblyName");

}

return Activator.CreateInstance(assemblyName, typeName);

}

Saludos, DJK

Pedro  Herrarte  Sánchez
Activator, crear objetos a partir de texto
Pedro Herrarte Sánchez

Pedro Herrarte, es consultor independiente, ofreciendo servicios de consultoría, análisis, desarrollo y formación. Posee mas de diez años de experiencia trabajando para las principales empresas de España. Es especialista en tecnologías .NET, entornos Web (ASP.NET, ASP.NET MVC,jQuery, HTML5), bases de datos (SQL Server y ORACLE) e integración de sistemas. Es experto en desarrollo (C#, VB.Net, T-SQL, PL/SQL, , ASP, CGI , C, Pro*C, Java, Essbase, Vignette, PowerBuilder y Visual Basic ...) y bases de datos (SQL Server y ORACLE). Pedro es MCP y MAP 2012, es fundador, diseñador y programador de www.devjoker.com..
Fecha de alta:29/10/2009
Última actualizacion:10/02/2012
Visitas totales:2844
Valorar el contenido:
Últimas consultas realizadas en los foros
Últimas preguntas sin contestar en los foros de devjoker.com