ダイナミックアセンブリをディスクに保存することは可能ですか?
-
20-09-2019 - |
質問
私は最近、Ayendeの本を買いました ブーにDSLを構築します (それを買って、読んでください、それは素晴らしいです)しかし、私は実装の問題に反対しています、そして、私は生成されたコードがどのように見えるかを見たいです。私は通常、リフレクターを使用してコードを調べますが、この場合、アセンブリは動的でメモリのみです。ダイナミックアセンブリをディスクに保存して、それらを反映できるようにする方法はありますか?
編集 /私の答え:
うわー、これに戻るのにしばらく時間がかかりました。残念ながら、私は元の質問から重要なことを残しました。
重要なビット:私は使用しています AyendeのRhinodslライブラリ 彼が本で勧めているように。 DSLENGINEのサブクラスでBoo Compilerにアクセスできます。これは次のようになります。
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"));
}
}
最小限に抑えて、私が望んだものを手に入れるには、1つの行を追加する必要があります...
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"));
}
}
これにより、コンパイラはアセンブリを私の〜 localSettings tempディレクトリに出力し、それからそれを反映することができました。その変更を加えると、プログラムの残りの部分が破壊されたことに注意することが重要です(Rhinodslはディスクに出力するため、メモリ内でアセンブリを見つけることができなくなったため、これはデバッグツールとしてのみ役立ちます。
解決
Boocompilerがインスタンス化されている場所を調べて、パイプラインを変更します CompileTomemory に CompiletOfile
他のヒント
はい AssemblyBuilder
クラスには Save
この目的のための方法。これに適したモードを使用する必要がありますが、これはおそらく RunAndSave
:
AssemblyBuilder builder =
AppDomain.CurrentDomain.DefineDynamicAssembly(
name, AssemblyBuilderAccess.RunAndSave);
// build assembly
builder.Save(path);
実行時にアセンブリを取得できる場合。
すなわち
Assembly assembly = typeof(YourDynamicType).Assembly;
その後、このアセンブリをAssemblyBuilderにキャストし、保存方法を呼び出すことができます。
AssemblyBuilder assemblyBuilder = (AssemblyBuilder)assembly;
assemblyBuilder.Save(yourPath);
簡単に行う方法があるかもしれませんが、WindBGの使用を気にしない場合は、メモリからロードされたマネージャーアセンブリを保存できます(WindBGはモジュールという用語を使用しますが、マネージャーアセンブリでも機能します)。
使用 !savemodule
アセンブリのアドレスを備えたコマンド。アドレスがない場合は、を使用します lm vm
モジュール名でコマンド。その後、通常のDLLアセンブリを取得します。これは、リフレクターで検査できることです。
もちろん、メモリ内のILコードを見るだけです。