2010-01-13 13 views
9

Compré recientemente el libro de Ayende Building DSLs in Boo (cómpralo, léelo, es increíble) pero me encuentro con un problema de implementación y quiero ver cómo se ve el código generado. Normalmente usaría el reflector para mirar el código, pero en este caso los ensamblajes son dinámicos y solo en la memoria. ¿Hay alguna forma de guardar ensamblajes dinámicos en el disco para que pueda reflejarlos?¿Es posible guardar un ensamblaje dinámico en el disco?

EDITAR/Mi respuesta:

Wow, tomó un tiempo para volver a éste. Lamentablemente, dejé una parte importante de la pregunta original.

Bit importante: Estoy usando Ayende's RhinoDSL library como él lo recomienda en el libro. Tengo acceso al compilador metida en mi subclase de DslEngine que se parece a esto:

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 cambiar el menos posible y que lo que quería que necesitaba para añadir una línea ...

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

Este hizo que el compilador enviara el ensamblado a mi directorio ~ ~ LocalSettings \ Temp y luego pude reflejarlo. Es importante tener en cuenta que realizar ese cambio provocó que el resto del programa se rompa (RhinoDSL ya no pudo encontrar los ensamblados en la memoria porque los elaboré en el disco), por lo que esto solo es útil como herramienta de depuración.

+0

Uso serialización de objetos XML?!. – serhio

+0

¿creas esos ensamblajes a través de CodeDom? –

Respuesta

4

Mirar hacia arriba, donde se crea una instancia BooCompiler, cambie la tubería de CompileToMemory a CompileToFile

+0

Esto es lo que finalmente me llevó a la respuesta que necesitaba, así que lo acepto, señor. –

4

Sí, la clase AssemblyBuilder tiene un método Save para este propósito. Es necesario utilizar el modo apropiado para esto, que es lo más probable RunAndSave:

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

El ensamblado ya está creado para mí en la memoria por el compilador Boo. Por lo tanto, no tengo acceso al generador ... –

+0

Es un ensamblaje dinámico, y si no se ha guardado y cargado desde el disco, debería enviarse a 'AssemblyBuilder' en ese caso. –

+1

@David M: Hmm ... cuando selecciono y presiono el método guardar, obtengo una InvalidOperationException diciendo que ha sido guardada. –

0

Si usted puede conseguir la Asamblea en tiempo de ejecución.

decir

Assembly assembly = typeof(YourDynamicType).Assembly; 

A continuación, puede lanzar este conjunto en AssemblyBuilder y llamar al método Save.

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

En realidad, el molde funciona, pero cuando ejecuto el método de guardar, muere diciendo que el ensamblado ya se ha guardado ... –

0

Puede haber una manera más fácil de hacerlo, pero si no les importa usar WinDbg para poder guardar cargado ensamblado administrado desde la memoria (WinDbg utiliza el módulo plazo, pero funciona para los ensamblados administrados, así)

Utilice el comando !savemodule con la dirección del conjunto. Si no tiene la dirección, use el comando lm vm con el nombre del módulo. A continuación, obtendrá un conjunto DLL común, que puede inspeccionar en Reflector.

Por supuesto, también puede consultar el código IL en la memoria.

Cuestiones relacionadas