2009-04-02 19 views
7

Me han cargado con el uso de una biblioteca interna de acceso a datos que efectivamente pasa XML a un procedimiento almacenado, que devuelve XML. No hay nada que pueda hacer sobre esto. Traté de aprobar ActiveRecord, pero mi solicitud fue rechazada. Sin embargo, usando el excelente código provisto en http://blog.bodurov.com/Post.aspx?postID=27, agregué un método de extensión a IEnumerable que convierte los pares clave-valor que yo hago del XML irregular volviendo a objetos muy tipados, ¡completos con nombres de propiedad!¿Cómo adjunto un método a un tipo de C# creado dinámicamente en tiempo de ejecución?

Este:

dict["keyName1"] 

convierte

MyObject.keyName1 

Ahora, la interfaz es compatible con el enlace de datos! ¡Muy genial! Sin embargo, me gustaría dar un paso más. Quiero que los objetos emitidos también tengan los métodos Save(), de modo que pueda simular el patrón ActiveRecord y proporcionar a mis chicos de la web una capa de objetos intuitiva para utilizar desde ASP.net.

¿Cómo escribo un método en Visual Studio, en código fuente, y lo adjunto en tiempo de ejecución a los objetos emitidos? No estoy interesado en (o calificado para) ensamblaje de escritura o IL. Me gustaría hacer esto en C#. Esta es mi primera pregunta de StackOverflow y estoy publicando esto con el IE6 requerido por la compañía, así que sean amables.

Respuesta

2

Según lo que deduzco de ese artículo, está creando tipos anónimos para usted, y lo está usando para obtener los valores. Si ese es el caso, no hay una manera fácil de agregar métodos a esos objetos. Sin embargo, si la estructura XML será la misma cada vez que se ejecute el SP, ¿por qué no crear una clase concreta que tenga todas las propiedades que necesita y rellenar una colección de esos objetos usted mismo con el XML? De esta manera, se puede añadir fácilmente cualquier método que necesita directamente en la clase ...

EDIT: Sobre la base de nuestra discusión en los comentarios, aquí hay un pensamiento:

En el código ahí, cuando está la construcción del tipo, estás usando: ModuleBuilder.DefineType. Hay una sobrecarga en DefineType que toma un tipo para extender. Link.. Por lo tanto, cree una interfaz (en caso de que no tenga que tener ningún método) y cuando esté creando dinámicamente el tipo, amplíe esa interfaz utilizando la sobrecarga a la que lo vinculé. A continuación, cree un método de extensión en esa interfaz que haga el Guardar().

Hay otra sobrecarga que pueda ser de su interés que toma un tipo de extender, e interfaces:

http://msdn.microsoft.com/en-us/library/f53tx4x8.aspx

Edit2: Ejemplo de código:

primer lugar, crear una interfaz:

public interface ISaveExtentable //I suck at naming stuff :-p 
{ 

} 

Luego, en el código que le gustaba en ese sitio, encontrará un método llamado: GetTypeBuilder. Cambiarlo a esto:

 private static TypeBuilder GetTypeBuilder(string typeSigniture) 
     { 
      AssemblyName an = new AssemblyName("TempAssembly" + typeSigniture); 
      AssemblyBuilder assemblyBuilder = 
       AppDomain.CurrentDomain.DefineDynamicAssembly(
        an, AssemblyBuilderAccess.Run); 
      ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); 

      TypeBuilder tb = moduleBuilder.DefineType("TempType" + typeSigniture 
           , TypeAttributes.Public | 
           TypeAttributes.Class | 
           TypeAttributes.AutoClass | 
           TypeAttributes.AnsiClass | 
           TypeAttributes.BeforeFieldInit | 
           TypeAttributes.AutoLayout 
           , typeof(object), new Type[] {typeof(ISaveExtentable)}); 
      return tb; 
     } 

A continuación, cree un método de extensión en esa interfaz de hacer el salve:

public static class SaveExtendableExtensions 
    { 
      public static void Save(this ISaveExtentable ise) 
      { 
       //implement save functionality. 
      } 
    } 

lo más probable es necesario utilizar la reflexión en su método Save para obtener toda la propiedades ya que el tipo fue creado dinámicamente.

+0

"si la estructura XML será el mismo cada vez que el SP ejecuta" me sale BRD 1245 RFW 3456 Nombre del Proyecto! etc con diferentes atributos cada vez :( –

+0

Sí, pero estoy seguro de que hay una lista de atributos que están disponibles para elegir. Pon todos esos atributos en la clase como campos Nullable (si son tipos de valor) y poblar solo los que recibe. No creo que necesite usar alguna solución loca para construir un tipo dinámicamente ... – BFree

+0

El XML se genera dinámicamente y no quiero tener que mantener una biblioteca de clases concretas para cada permutación –

1

Creo que esto se conoce como mezclas que no están directa o fácilmente disponibles en .net. Sin embargo, como yo lo entiendo, esta es una de las razones principales por las que se diseñó el marco LinFu.

Cuestiones relacionadas