2009-04-02 16 views
7

Mi è stato affidato l'utilizzo di una libreria di accesso ai dati interna che è passata in modo efficace XML a una stored procedure, che restituisce XML. Non c'è nulla che io possa fare al riguardo. Ho provato ad ottenere l'approvazione di ActiveRecord, ma la mia richiesta è stata rifiutata. Tuttavia, usando l'eccellente codice fornito a http://blog.bodurov.com/Post.aspx?postID=27, ho aggiunto un metodo di estensione a IEnumerable che converte le coppie di valori-chiave che ricavo dall'aspetto XML ragged in oggetti fortemente tipizzati, completi di nomi di proprietà!Come si allega un metodo a un tipo C# creato in modo dinamico in fase di runtime?

questo:

dict["keyName1"] 

diventa

MyObject.keyName1 

Ora l'interfaccia supporta l'associazione dati! Molto carino! Mi piacerebbe fare un ulteriore passo avanti, però. Voglio che gli oggetti emessi abbiano anche i metodi Save(), in modo che io possa scimmiottare il pattern ActiveRecord e fornire ai miei ragazzi del web un livello di oggetto intuitivo da utilizzare da ASP.net.

Come scrivere un metodo in Visual Studio, nel codice sorgente e collegarlo in fase di runtime agli oggetti emessi? Non sono interessato a (o qualificato per) assemblaggio di scrittura o IL. Mi piacerebbe farlo in C#. Questa è la mia prima domanda StackOverflow e la sto postando con IE6 imposto dall'azienda, quindi per favore sii gentile.

risposta

2

Da quello che ho trovato su quell'articolo, sta creando tipi anonimi per te, e lo stai usando per ottenere i valori. Se questo è il caso, non c'è un modo semplice per aggiungere metodi a quegli oggetti. Tuttavia, se la struttura XML sarà la stessa ogni volta che l'SP viene eseguito, perché non creare una classe concreta con tutte le proprietà necessarie e compilare personalmente una raccolta di tali oggetti con XML. In questo modo, è possibile aggiungere facilmente i metodi necessari direttamente nella classe ...

EDIT: Sulla base della nostra discussione nei commenti, ecco un pensiero:

Nel codice, quando si sta costruendo il tipo, stai usando: ModuleBuilder.DefineType. C'è un sovraccarico in DefineType che richiede un tipo di estensione. Link.. Pertanto, crea un'interfaccia (non deve avere alcun metodo in esso) e, quando stai generando dinamicamente il tipo, estendi l'interfaccia usando l'overload a cui ti ho collegato. Quindi creare un metodo di estensione su quell'interfaccia che fa Save().

C'è un altro overload che potrebbero interessare che richiede un tipo di estendere, e interfacce:

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

EDIT2: Esempio di codice:

In primo luogo, creare un'interfaccia:

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

} 

Quindi, nel codice che ti piaceva in quel sito, troverai un metodo chiamato: GetTypeBuilder. Cambiarlo in questo:

 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; 
     } 

Quindi, creare un metodo di estensione su tale interfaccia per fare il salvataggio:

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

che molto probabilmente bisogno di utilizzare la riflessione nel vostro metodo Save per ottenere tutte le proprietà poiché il tipo è stato creato dinamicamente.

+0

"se la struttura XML sarà lo stesso ogni volta che il SP esegue" ottengo BRD 1245 RFW 3456 Nome del progetto! con attributi diversi ogni volta :( –

+0

Sì, ma sono sicuro che c'è un elenco di attributi disponibili tra cui scegliere. Mettere tutti gli attributi nella classe come campi Nullable (se si tratta di tipi di valore) e popola solo quelli che torni. Non penso che tu debba usare una soluzione pazzesca per costruire un tipo in modo dinamico ... – BFree

+0

L'XML è generato dinamicamente e non voglio dover mantenere una libreria di classi concrete per ogni permutazione. –

1

Penso che questo si chiami mix-in che non sono direttamente o facilmente disponibili in .net. Tuttavia, a quanto ho capito, questo è uno dei motivi principali per cui è stato progettato il framework LinFu.

Problemi correlati