2010-01-13 4 views
9

Ich kaufte vor kurzem Ayendes Buch Building DSLs in Boo (kaufen Sie es, lasen Sie es, es ist fantastisch), aber ich stoße auf ein Implementierungsproblem, und ich möchte sehen, wie der generierte Code aussieht. Ich würde normalerweise Reflektor verwenden, um den Code zu betrachten, aber in diesem Fall sind die Assemblies dynamisch und nur im Speicher. Gibt es eine Möglichkeit, dynamische Assemblys auf der Festplatte zu speichern, damit ich sie wiedergeben kann?Kann eine dynamische Assembly auf Festplatte gespeichert werden?

EDIT/Meine Antwort:

Wow, dauerte es eine Weile wieder in dieses zu kommen. Leider habe ich ein wichtiges Stück von der ursprünglichen Frage entfernt.

Wichtiges Bit: Ich verwende Ayende's RhinoDSL library, wie er in dem Buch empfiehlt. Ich habe Zugang zu den boo Compiler in meiner Unterklasse von DslEngine, die wie folgt aussehen:

public class JobEngine : DslEngine 
{ 
    protected override void CustomizeCompiler(Boo.Lang.Compiler.BooCompiler compiler, Boo.Lang.Compiler.CompilerPipeline pipeline, string[] urls) 
    { 
     pipeline.Insert(1, new ImplicitBaseClassCompilerStep(typeof (JobBase), "Prepare", "JobLanguage", "log4net", "Quartz")); 
    } 
} 

Um die am wenigsten zu ändern und bekommen, was ich wollte ich eine Zeile hinzufügen benötigt ...

public class JobEngine : DslEngine 
{ 
    protected override void CustomizeCompiler(Boo.Lang.Compiler.BooCompiler compiler, Boo.Lang.Compiler.CompilerPipeline pipeline, string[] urls) 
    { 
     compiler.Parameters.GenerateInMemory = false; // <--- This one. 
     pipeline.Insert(1, new ImplicitBaseClassCompilerStep(typeof (JobBase), "Prepare", "JobLanguage", "log4net", "Quartz")); 
    } 
} 

Diese hat den Compiler veranlaßt, die Assembly in mein ~ \ LocalSettings \ Temp-Verzeichnis auszugeben, und dann könnte ich es dann reflektieren. Es ist wichtig zu beachten, dass diese Änderung dazu führte, dass der Rest des Programms unterbrochen wurde (RhinoDSL konnte die Assemblies nicht mehr im Speicher finden, weil ich sie auf die Festplatte ausgegeben habe). Dies ist nur als Debugging-Tool nützlich.

+0

Verwenden Objekt XML-Serialisierung die Pipeline von CompileToMemory zu CompileToFile ändern?!. – serhio

+0

erstellen Sie diese Assemblys über CodeDom? –

Antwort

4

nachschlagen, wo BooCompiler instanziert wird,

+0

Dies führte mich schließlich zu der Antwort, die ich brauchte, also akzeptiere ich Sie. –

4

Ja, die AssemblyBuilder Klasse hat eine Save Methode für diesen Zweck. Sie müssen den entsprechenden Modus für diese verwenden, die meisten wahrscheinlich RunAndSave:

AssemblyBuilder builder = 
    AppDomain.CurrentDomain.DefineDynamicAssembly(
     name, AssemblyBuilderAccess.RunAndSave); 
// build assembly 
builder.Save(path); 
+0

Die Assembly ist bereits für mich im Speicher vom Boo Compiler erstellt worden. So habe ich keinen Zugriff auf den Builder ... –

+0

Es ist eine dynamische Assembly, und wenn es nicht gespeichert und von der Festplatte geladen wurde, sollte in diesem Fall zu 'AssemblyBuilder'. –

+1

@David M: Hmm ... wenn ich die Save-Methode aktiviere und drücke, bekomme ich eine InvalidOperationException, die besagt, dass sie gespeichert wurde. –

0

Wenn Sie die Assembly zur Laufzeit bekommen.

heißt

Assembly assembly = typeof(YourDynamicType).Assembly; 

Sie können dann diese Baugruppe in Assembly gegossen und die Save-Methode aufrufen.

AssemblyBuilder assemblyBuilder = (AssemblyBuilder)assembly; 
assemblyBuilder.Save(yourPath); 
+1

Wirklich funktioniert die Besetzung, aber wenn ich die Speichermethode ausführen, stirbt es, sagend, dass die Versammlung bereits gespeichert worden ist ... –

0

Es kann ein einfacher Weg, es zu tun, aber wenn Sie nicht WinDbg mit nichts dagegen können Sie eine aus dem Speicher geladen verwaltete Assembly speichern (WinDbg den Begriff Modul verwendet, aber es funktioniert auch für verwaltete Baugruppen).

Verwenden Sie den Befehl !savemodule mit der Adresse der Baugruppe. Wenn Sie die Adresse nicht haben, verwenden Sie den Befehl lm vm mit dem Modulnamen. Anschließend erhalten Sie eine reguläre DLL-Assembly, die Sie in Reflector überprüfen können.

Natürlich können Sie auch nur den IL-Code im Speicher betrachten.

Verwandte Themen