2009-04-02 20 views
7

Ich wurde mit der Verwendung einer internen Datenzugriffsbibliothek ausgestattet, die effektiv an eine gespeicherte Prozedur übergeben wird, die XML zurückgibt. Ich kann nichts dagegen tun. Ich habe versucht, ActiveRecord zu genehmigen, aber meine Anfrage wurde abgelehnt. Unter Verwendung des exzellenten Codes, der unter http://blog.bodurov.com/Post.aspx?postID=27 bereitgestellt wird, fügte ich IEnumerable jedoch eine Erweiterungsmethode hinzu, die die Schlüssel/Wert-Paare, die ich aus dem zerlumpten XML herstelle, in stark typisierte Objekte konvertiert, komplett mit Eigenschaftsnamen! DieseWie füge ich eine Methode an einen dynamisch erstellten C# -Typ zur Laufzeit an?

:

dict["keyName1"] 

wird

MyObject.keyName1 

Nun ist die Schnittstelle unterstützt Datenbindung! Ziemlich cool! Ich möchte aber noch einen Schritt weiter gehen. Ich möchte, dass die emittierten Objekte über Save() -Methoden verfügen, so dass ich das ActiveRecord-Muster nachbilden und meinen Web-Leuten eine intuitive Objekt-Ebene zur Verfügung stellen kann, die von ASP.net verwendet werden kann.

Wie schreibe ich eine Methode in Visual Studio im Quellcode und an die emittierten Objekte zur Laufzeit anfügen? Ich bin nicht daran interessiert (oder dafür qualifiziert), Assembly oder IL zu schreiben. Ich würde das gerne in C# machen. Dies ist meine erste StackOverflow-Frage und ich poste dies mit dem vom Unternehmen beauftragten IE6, also sei bitte sanft.

Antwort

2

Von dem, was ich zu diesem Artikel erfasse, erstellt es anonyme Typen für Sie, und Sie verwenden das, um die Werte zu erhalten. Wenn das der Fall ist, gibt es keine einfache Möglichkeit, Methoden zu diesen Objekten hinzuzufügen. Wenn die XML-Struktur jedoch bei jeder Ausführung des SP identisch ist, erstellen Sie eine konkrete Klasse, die alle erforderlichen Eigenschaften aufweist, und füllen Sie eine Auflistung dieser Objekte selbst mit dem XML-Code. Auf diese Weise können Sie ganz einfach alle Methoden hinzufügen, die Sie direkt in die Klasse benötigen ...

EDIT: auf unsere Diskussion in den Kommentaren Basierend, hier ist ein Gedanke:

Im Code dort, wenn Sie bauen up the type verwenden Sie: ModuleBuilder.DefineType. Es gibt eine Überladung zu DefineType, die einen Typ zum Erweitern nimmt. Link.. Erstellen Sie daher eine Schnittstelle (das Ereignis muss keine Methoden enthalten), und wenn Sie den Typ dynamisch aufbauen, erweitern Sie diese Schnittstelle mit der Überladung, mit der ich Sie verlinkt habe. Erstellen Sie dann eine Erweiterungsmethode für diese Schnittstelle, die Save() ausführt.

Es gibt eine andere Überladung, die von Interesse sein können, die eine Art nimmt zu erweitern und Schnittstellen:

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

EDIT2: Codebeispiel:

Zuerst eine Schnittstelle erstellen:

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

} 

Dann finden Sie in dem Code, den Sie auf dieser Site gerne hätten, eine Methode namens GetTypeBuilder. Ändern Sie ihn auf diese:

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

Dann erstellen Sie eine Erweiterungsmethode auf dieser Schnittstelle das zu tun, sparen:

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

Sie werden höchstwahrscheinlich Reflexion in Ihrer Save-Methode verwenden, müssen alle bekommen die Eigenschaften, da der Typ dynamisch erstellt wurde.

+0

"wenn die XML-Struktur jedes Mal die gleiche sein wird, führt die SP" I BRD 1245 RFW 3456 Name des Projekts erhalten! etc mit unterschiedlichen Attributen jedes Mal :( –

+0

Ja, aber ich bin sicher, dass eine Liste von Attributen gibt es die aus verfügbar sind zu wählen. Legen Sie alle diese Attribute in der Klasse als Nullable Felder (wenn sie Werttypen) Ich denke nicht, dass Sie eine verrückte Lösung verwenden müssen, um dynamisch einen Typ zu erstellen ... – BFree

+0

Das XML wird dynamisch generiert und ich möchte keine Bibliothek von konkreten Klassen verwalten müssen Für jede Permutation –

1

Ich denke, das nennt man Mix-Ins, die nicht direkt oder einfach in .net verfügbar sind. Wie ich jedoch verstehe, ist dies einer der Hauptgründe, warum das LinFu Framework entworfen wurde.

Verwandte Themen