동적 어셈블리를 디스크에 저장할 수 있습니까?
-
20-09-2019 - |
문제
나는 최근에 Ayende의 책을 샀다 부에 DSL 건물 (구매, 읽으십시오. 굉장합니다) 그러나 나는 구현 문제에 반대하는데 생성 된 코드의 모습을보고 싶습니다. 나는 일반적으로 반사기를 사용하여 코드를 보지만이 경우 어셈블리는 역동적이며 메모리에만 있습니다. 동적 어셈블리를 디스크에 저장하여 반사 할 수있는 방법이 있습니까?
편집 / 내 대답:
와우, 이것으로 돌아 오는 데 시간이 걸렸습니다. 불행히도 나는 원래 질문에서 중요한 부분을 남겼습니다.
중요한 비트 : 사용 중입니다 Ayende의 Rhinodsl 라이브러리 그가 책에서 추천하는 것처럼. dslengine 서브 클래스에서 Boo 컴파일러에 액세스 할 수 있습니다.
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
클래스는 a Save
이 목적을위한 방법. 이를 위해 적절한 모드를 사용해야합니다. RunAndSave
:
AssemblyBuilder builder =
AppDomain.CurrentDomain.DefineDynamicAssembly(
name, AssemblyBuilderAccess.RunAndSave);
// build assembly
builder.Save(path);
런타임에 어셈블리를 얻을 수있는 경우.
즉
Assembly assembly = typeof(YourDynamicType).Assembly;
그런 다음이 어셈블리를 AssemblyBuilder에 시전하고 저장 방법을 호출 할 수 있습니다.
AssemblyBuilder assemblyBuilder = (AssemblyBuilder)assembly;
assemblyBuilder.Save(yourPath);
더 쉬운 방법이있을 수 있지만 WindBG를 사용하지 않으면 메모리에서로드 된 관리 어셈블리를 저장할 수 있습니다 (WINDBG는 용어 모듈을 사용하지만 관리 조립품에도 작동합니다).
사용 !savemodule
어셈블리의 주소로 명령하십시오. 주소가없는 경우 사용하십시오 lm vm
모듈 이름으로 명령. 이어서 정기적 인 DLL 어셈블리를 얻으려면 반사기를 검사 할 수 있습니다.
물론 메모리에서 IL 코드를 볼 수도 있습니다.