10

最近、Ayendeの本Building DSLs in Booを購入しました(購入して読んでください。すばらしいです)が、実装の問題が発生しているので、生成されたコードがどのようになるかを確認したいと思います。私は通常、リフレクターを使用してコードを確認しますが、この場合、アセンブリは動的であり、メモリ内にのみ存在します。動的アセンブリをディスクに保存して、それらを反映できるようにする方法はありますか?

編集/私の答え

うわー、これに戻るのに少し時間がかかりました。残念ながら、私は元の質問から重要な部分を省きました。

重要なビット:本で推奨されているように、私はAyendeのRhinoDSLライブラリを使用しています。DslEngineのサブクラスにあるbooコンパイラにアクセスできます。これは次のようになります。

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は、アセンブリをディスクに出力したため、メモリ内のアセンブリを見つけることができなくなりました)。したがって、これはデバッグツールとしてのみ役立ちます。

4

4 に答える 4

5

BooCompiler がインスタンス化されている場所を調べ、パイプラインを CompileToMemory からCompileToFile変更します。

于 2010-01-26T02:14:16.583 に答える
4

はい、AssemblyBuilderクラスにはSaveこの目的のためのメソッドがあります。これには適切なモードを使用する必要がありますRunAndSave

AssemblyBuilder builder =
    AppDomain.CurrentDomain.DefineDynamicAssembly(
        name, AssemblyBuilderAccess.RunAndSave);
// build assembly
builder.Save(path);
于 2010-01-13T16:33:12.203 に答える
1

もっと簡単な方法があるかもしれませんが、WinDbg を使用してもかまわない場合は、読み込まれたマネージ アセンブリをメモリから保存できます (WinDbg ではモジュールという用語が使用されますが、マネージ アセンブリに対しても機能します)。

!savemoduleアセンブリのアドレスでコマンドを使用します。アドレスがわからない場合はlm vm、モジュール名を指定してコマンドを使用してください。その後、Reflector で検査できる通常の DLL アセンブリを取得します。

もちろん、メモリ内の IL コードを確認することもできます。

于 2010-01-13T16:33:49.397 に答える
0

実行時にアセンブリを取得できる場合。

すなわち

Assembly assembly = typeof(YourDynamicType).Assembly;

その後、このアセンブリを AssemblyBuilder にキャストし、Save メソッドを呼び出すことができます。

AssemblyBuilder assemblyBuilder = (AssemblyBuilder)assembly;
assemblyBuilder.Save(yourPath);
于 2010-01-13T16:33:42.657 に答える