2009-03-17 21 views
5

Estoy usando LINQ-to-XML para consultar un archivo de una lista de objetos. Todos tienen la misma estructura (un conjunto de opciones, una lista de parámetros de longitud indeterminada). Basado en su nombre en el archivo XML, quiero usar los parámetros para cosas completamente diferentes, así que hice subclases de este objeto.¿Cómo puedo invocar dinámicamente un constructor en C#?

Mi pregunta es: ¿cómo invoco el constructor correcto dinámicamente, sin hacer algo como una declaración de caso? ¿O la solución para instanciar elegantemente diferentes subclases de XML se encuentra en otra parte?

class Object1 
{ 
    string name; 
    OptionObj opt; 
    List<Param> parameters; 
} 

class sonOfObject : Object1 
{ 
    public void ExecuteSomething() 
    { 
     //do something with the parameters 
    } 
} 

class secondSonOfObject : Object1 
{ 
    public void ExecuteSomething() 
    { 
     //do something entirely different with the parameters 
    } 
} 

var query = from x in xmlDoc.Descendants("Object") 
    select new Object 
    { 
     //select the object from the XML 
    } 

Después de este trozo de código que podría utilizar un constructor de copia para hacer una sonOfObject del objeto de consulta más genérica. Pero, ¿cómo lo hago dinámicamente, en función del nombre de la clase infantil?

Sé que se puede obtener a partir de un tipo MethodInfo e invocarlo ala ...

MethodInfo m = t.GetMethod(someName); 
m.Invoke(yourObj, null); 

Pero eso significaría que tendría que crear una instancia de 9 o 10 de estos objetos de clase del niño (y obtener el tipo para cada uno de ellos), y aún termina en algún tipo de declaración de caso.

¿Existe alguna manera más elegante de invocar dinámicamente a los constructores de clase infantil?

Respuesta

3

Para que una clase participe en este esquema, lo marcaría con un atributo personalizado, que le da un "nombre XML".

Luego use la reflexión para encontrar todos los Type s marcados con ese atributo y póngalos en un Dictionary<string, Type>. En este punto, debe decidir cómo va a encontrar otros ensamblajes que puedan contribuir con tipos al sistema. Un enfoque simple es buscar otros archivos con la extensión .DLL en el mismo directorio.

Entonces cada vez que tenga cuerda desde el XML que desea utilizar para crear una instancia de la correspondiente Type, sólo tiene que buscar la Type en el Dictionary por su nombre y llamar Type.GetConstructor y ConstructorInfo.Invoke.

La ventaja de esto es que el identificador en el XML está separado del diseño físico de su código: puede mover tipos en ensamblajes o cambiarles el nombre sin invalidar los archivos XML antiguos.

+0

+1 Después de volver a leer el OP, creo que esta es realmente la mejor solución. –

Cuestiones relacionadas