Можно ли сохранить динамическую сборку на диск?

StackOverflow https://stackoverflow.com/questions/2058340

  •  20-09-2019
  •  | 
  •  

Вопрос

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

Редактировать / мой ответ:

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

Важный бит: я использую Библиотека Ayende Rhinodsl как он рекомендует в книге. У меня есть доступ к компилятору BOO в моем подклассе 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 больше не мог найти сборки в памяти, потому что я выводит их на диск), так что это полезно только в качестве инструмента отладки.

Это было полезно?

Решение

Посмотрите, где строитель строительства, измените трубопровод с Компилетомом к Комбилетофиль

Другие советы

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

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

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

т.е.

Assembly assembly = typeof(YourDynamicType).Assembly;

Затем вы можете бросить эту сборку в сборщик сборки и вызвать метод сохранения.

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

There may be an easier way to do it, but if you don't mind using WinDbg you can save any loaded managed assembly from memory (WinDbg uses the term module, but it works for managed assemblies as well).

Use the !savemodule command with the address of the assembly. If you don't have the address use the lm vm command with the module name. Following that you get a regular DLL assembly, that you can inspect in Reflector.

Of course you may also just look at the IL code in memory.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top