Pergunta

Eu comprei recentemente o livro de Ayende Construindo DSLs em Boo (Compre, leia, é incrível) Mas estou enfrentando um problema de implementação e quero ver como é o código gerado. Normalmente, eu usaria o refletor para examinar o código, mas nesse caso os assemblies são dinâmicos e somente na memória. Existe uma maneira de salvar conjuntos dinâmicos no disco para que eu possa refleti -los?

Editar / minha resposta:

Uau, demorou um pouco para voltar a este. Infelizmente, deixei um pouco importante da pergunta original.

Bit importante: estou usando Biblioteca Rhinodsl de Ayende como ele recomenda no livro. Tenho acesso ao compilador de boo na minha subclasse de dslegine, que se parece com o seguinte:

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

Para mudar o mínimo e obter o que eu queria, precisava adicionar uma linha ...

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

Isso fez com que o compilador emitisse a montagem para o meu diretório ~ LocalSettings Temp e então eu poderia refleti -lo. É importante observar que fazer essa alteração fez com que o restante do programa quebrasse (o rhinodsl não conseguiu mais encontrar os conjuntos na memória porque eu os produzi para o disco), então isso é útil apenas como uma ferramenta de depuração.

Foi útil?

Solução

Procure onde o boocompiler é instanciado, altere o oleoduto de Compiletomemory para Compiletofile

Outras dicas

Sim o AssemblyBuilder A classe tem um Save método para esse fim. Você precisa usar o modo apropriado para isso, o que é provavelmente RunAndSave:

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

Se você pode obter a assembléia em tempo de execução.

ou seja

Assembly assembly = typeof(YourDynamicType).Assembly;

Em seguida, você pode lançar esta montagem no AssemblyBuilder e chamar o método de salvamento.

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

Pode haver uma maneira mais fácil de fazê -lo, mas se você não se importa de usar o WindBG, poderá salvar qualquer montagem gerenciada carregada da memória (o WindBG usa o termo módulo, mas também funciona para assemblies gerenciados).

Use o !savemodule comando com o endereço da Assembléia. Se você não tiver o endereço, use o lm vm comando com o nome do módulo. Depois disso, você obtém um conjunto regular de DLL, que pode inspecionar no refletor.

É claro que você também pode apenas olhar para o código IL na memória.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top