2010-01-13 2 views
9

나는 최근에 Ayende의 책 Building DSLs in Boo (구매, 그것을 읽고, 끝내 준다)을 구입했지만 구현 문제에 대해 생각해 보았고 생성 된 코드가 어떻게 보이는지 알고 싶다. 나는 일반적으로 코드를보기 위해 리플렉터를 사용하지만,이 경우 어셈블리는 동적이며 메모리에만 있습니다. 동적 어셈블리를 디스크에 저장하여 반영 할 수 있습니까?동적 어셈블리를 디스크에 저장할 수 있습니까?

편집/내 대답는 :

와우, 그것은 다시 이것에 와서 잠시했다. 불행히도 원래의 질문에서 중요한 부분을 벗어났습니다.

중요 비트 : 나는이 책에서 권하는대로 Ayende's RhinoDSL library을 사용하고 있습니다. ...

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

이를

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

는 적어도 변경하고 내가 한 줄을 추가 할 필요가 원하는 것을 얻으려면 : I는 다음과 같습니다 DslEngine의 내 서브 클래스에서 야유 컴파일러에 액세스 할 수 컴파일러가 어셈블리를 내 ~ \ LocalSettings \ Temp 디렉터리에 출력하도록 한 다음이를 반영 할 수있었습니다. 이러한 변경으로 인해 나머지 프로그램이 중단되었습니다 (RhinoDSL은 디스크에 출력하기 때문에 더 이상 메모리에서 어셈블리를 찾을 수 없음), 이는 디버깅 도구로만 유용합니다.

+0

CompileToFile에 객체 XML 직렬화에서 파이프 라인을 변경 조회?!. – serhio

+0

CodeDom을 통해 어셈블리를 만드시겠습니까? –

답변

4

이 BooCompiler가 인스턴스화되는 경우, CompileToMemory 사용

+0

이것이 궁극적으로 내가 필요한 답변으로 나를 인도했습니다. –

4

예, AssemblyBuilder 클래스에는이 목적으로 Save 메서드가 있습니다. 런타임에서 어셈블리를 얻을 수있는 경우

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

어셈블리는 이미 Boo 컴파일러에 의해 메모리에 내장되어 있습니다. 따라서 빌더에 접근 할 수 없습니다. –

+0

동적 어셈블리이고, 디스크에서 저장되고로드되지 않은 경우,이 경우에는'AssemblyBuilder'로 변환해야합니다. –

+1

@David M : 흠 ... 내가 캐스팅하고 저장 메소드를 눌렀을 때 저장되었음을 나타내는 InvalidOperationException이 발생합니다. –

0

: 당신은 가장 가능성 RunAndSave이며 이에 대한 적절한 모드를 사용해야합니다.

Assembly assembly = typeof(YourDynamicType).Assembly; 

그런 다음 AssemblyBuilder에이 어셈블리를 캐스팅하고 저장 메서드를 호출 할 수 있습니다.

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

실제로 캐스팅은 작동하지만 저장 방법을 실행할 때 어셈블리가 이미 저장되었다고 말하면서 죽습니다 ... –

0

이 그것을 할 수있는 쉬운 방법이 될 수 있지만, 당신은 WinDbg를를 사용 괜찮다면 당신은 (WinDbg는이 용어 모듈을 사용하는 메모리에서 관리되는 어셈블리를로드 절약 할 수 있지만, 그것뿐만 아니라 관리 어셈블리 작동).

!savemodule 명령을 어셈블리 주소와 함께 사용하십시오. 주소가없는 경우 모듈 이름과 함께 lm vm 명령을 사용하십시오. 그런 다음 반사경에서 검사 할 수있는 일반 DLL 어셈블리를 얻습니다.

물론 메모리의 일리노이 코드를 볼 수도 있습니다.

관련 문제