Frage

Ich habe kürzlich Ayende's Buch gekauft Bau von DSLs in Boo (Kaufen Sie es, lesen Sie es, es ist großartig) Aber ich stehe auf ein Implementierungsproblem und möchte sehen, wie der generierte Code aussieht. Normalerweise würde ich Reflektor verwenden, um den Code zu betrachten, aber in diesem Fall sind die Baugruppen dynamisch und nur im Speicher. Gibt es eine Möglichkeit, dynamische Baugruppen auf der Festplatte zu speichern, damit ich sie reflektieren kann?

Bearbeiten / meine Antwort:

Wow, es hat eine Weile gedauert, um zu diesem zurückzukehren. Leider habe ich ein wichtiges Stück aus der ursprünglichen Frage entfernt.

Wichtiges Stück: Ich benutze Ayende's Rhinodsl Library wie er im Buch empfiehlt. Ich habe Zugriff auf den Boo -Compiler in meiner Unterklasse von dslengine, die so aussieht:

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 am wenigsten zu ändern und zu bekommen, was ich wollte, musste ich eine Zeile hinzufügen ...

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

Dies führte dazu, dass der Compiler die Baugruppe in mein Verzeichnis von ~ localettings temp ausgab, und dann konnte ich sie dann widerspiegeln. Es ist wichtig zu beachten, dass das Vorgehen dieser Änderung dazu führte, dass der Rest des Programms brechen (Rhinodsl konnte die Baugruppen im Speicher nicht mehr finden, weil ich sie auf die Festplatte ausgibt), daher ist dies nur als Debugging -Tool nützlich.

War es hilfreich?

Lösung

Schauen Sie nach, wo Boocompiler instanziiert ist, und ändern Sie die Pipeline von Compiletomemory zu CompiletoFile

Andere Tipps

Ja das AssemblyBuilder Klasse hat a Save Methode für diesen Zweck. Sie müssen den entsprechenden Modus dafür verwenden, was am wahrscheinlichsten ist RunAndSave:

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

Wenn Sie die Montage zur Laufzeit erhalten können.

dh

Assembly assembly = typeof(YourDynamicType).Assembly;

Sie können diese Baugruppe dann in AssemblyBuilder werfen und die Speichernmethode aufrufen.

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

Es kann eine einfachere Möglichkeit geben, dies zu tun. Wenn Sie jedoch nichts ausmachen, können Sie jede geladene verwaltete Montage vor dem Speicher speichern (Windbg verwendet das Begriffsmodul, funktioniert jedoch auch für verwaltete Baugruppen).

Verwenden Sie das !savemodule Befehl mit der Adresse der Baugruppe. Wenn Sie nicht die Adresse haben, verwenden Sie die lm vm Befehl mit dem Modulnamen. Anschließend erhalten Sie eine reguläre DLL -Baugruppe, die Sie im Reflektor inspizieren können.

Natürlich können Sie sich auch den IL -Code im Speicher ansehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top