Действительно ли возможно сохранить динамический блок на диск?

Я недавно купил букбилдинг Ayende DSLs в Шиканье (купите его, считайте его, это является потрясающим), но я наталкиваюсь на проблему реализации, и я хочу видеть то, на что похож сгенерированный код. Я обычно использовал бы отражатель для рассмотрения кода, но в этом случае блоки являются динамичными и только в памяти. Существует ли способ сохранить динамические блоки на диск так, чтобы я мог отразить их?

РЕДАКТИРОВАНИЕ / Мой Ответ:

Ничего себе, это взяло некоторое время для возвращения к этому. К сожалению, я оставил важный бит из исходного вопроса.

Важный Бит: я пользуюсь библиотекой RhinoDSL Ayende, как он рекомендует в книге. У меня есть доступ к компилятору шиканья в моем подклассе DslEngine, который похож на это:

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

Чтобы измениться меньше всего и добраться, что я хотел, я должен был добавить одну строку...

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 больше не мог находить блоки в памяти, потому что я произвел их к диску), таким образом, это только полезно как средство отладки.

10
задан Jason Punyon 18 May 2010 в 20:14
поделиться

4 ответа

Посмотрите, где создается буконтерий, измените трубопровод из Compitletomemory на CompiteretOfile

5
ответ дан 4 December 2019 в 01:57
поделиться

Да, класс AssemblyBuilder для этой цели имеет метод Save. Для этого необходимо использовать соответствующий режим, наиболее вероятным из которых является RunAndSave:

AssemblyBuilder builder =
    AppDomain.CurrentDomain.DefineDynamicAssembly(
        name, AssemblyBuilderAccess.RunAndSave);
// build assembly
builder.Save(path);
4
ответ дан 4 December 2019 в 01:57
поделиться

, если можно получить сборку во время выполнения. Т.е.

т.е.

Assembly assembly = typeof(YourDynamicType).Assembly;

Вы можете затем бросить эту сборку в AssemblyBuilder и вызвать метод Save.

AssemblyBuilder assemblyBuilder = (AssemblyBuilder)assembly;
assemblyBuilder.Save(yourPath);
0
ответ дан 4 December 2019 в 01:57
поделиться

Возможно, есть более простой способ, но если вы не возражаете против использования WinDbg, вы можете сохранить из памяти любую загруженную управляемую сборку (WinDbg использует термин "модуль", но он работает и для управляемых сборок).

Используйте команду !savemodule с адресом сборки. Если у Вас нет адреса, используйте команду lm vm с именем модуля. После этого вы получите обычную сборку DLL, которую можно проверить в рефлекторе.

Конечно, вы также можете просто посмотреть на код IL в памяти.

0
ответ дан 4 December 2019 в 01:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: