Question

J'ai récemment acheté le livre de Ayende bâtiment DSLs à Boo (acheter, de le lire, il est génial) mais je suis à venir contre un problème de mise en œuvre et je veux voir ce que le code généré ressemble. J'utiliser normalement réflecteur pour regarder le code, mais dans ce cas, les assemblées sont dynamiques et seulement dans la mémoire. Est-il possible d'enregistrer des ensembles dynamiques sur le disque afin que je puisse en tenir compte?

EDIT / Ma réponse :

Wow, il a fallu du temps pour revenir à celui-ci. Malheureusement, je suis parti un peu importante à partir de la question initiale.

Bit Important: J'utilise bibliothèque RhinoDSL de Ayende comme il recommande dans le livre. J'ai accès au compilateur boo dans mon sous-classe de DslEngine qui ressemble à ceci:

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

Pour modifier le moins et obtenir ce que je voulais que je devais ajouter une ligne ...

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

Cela a provoqué le compilateur à la sortie de l'ensemble à mes ~ \ LocalSettings \ Temp et je pourrait alors refléter. Il est important de noter que le fait que le changement a causé le reste du programme pour briser (RhinoDSL ne pouvait plus les assemblées en mémoire parce que la production je les ai sur le disque), de sorte que cela n'est utile comme outil de débogage.

Était-ce utile?

La solution

Regardez là où BooCompiler est instancié, changer le pipeline de CompileToMemory CompileToFile

Autres conseils

Oui, la classe AssemblyBuilder a une méthode Save à cet effet. Vous devez utiliser le mode approprié pour ce qui est le plus probable RunAndSave:

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

Si vous pouvez obtenir l'Assemblée lors de l'exécution.

i.e..

Assembly assembly = typeof(YourDynamicType).Assembly;

Vous pouvez ensuite lancer cet ensemble dans AssemblyBuilder et appeler la méthode Save.

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

Il peut y avoir un moyen plus facile de le faire, mais si cela ne vous dérange pas en utilisant WinDbg vous pouvez enregistrer tout ensemble géré chargé de la mémoire (WinDbg utilise le module terme, mais il fonctionne pour les assemblées gérées aussi bien).

Utilisez la commande !savemodule avec l'adresse de l'ensemble. Si vous ne possédez pas l'adresse utiliser la commande lm vm avec le nom du module. A la suite que vous obtenez un ensemble de DLL régulière, que vous pouvez consulter dans le réflecteur.

Bien sûr, vous pouvez aussi il suffit de regarder le code IL en mémoire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top