2011-03-11 3 views
4

어셈블리를 컴파일하는 데 CSharpCodeProvider를 사용하고 물리적 파일을 생성하고 싶지 않기 때문에 true로 설정 한 CompileParametersGenerateInMemory 속성이 있습니다.InMemory 컴파일 된 어셈블리를 현재 도메인에로드

컴파일 후 CompilerResults 걸릴 수 있으며 다음과 같은 작업을 수행 할 수 있습니다. -

 object x = cr.CompiledAssembly.CreateInstance("MyGeneratedClass"); 
Console.WriteLine(x); 

예상되는 출력을 얻었으므로 CreateInstance이 작동했습니다.

그러나 어셈블리에 대한 지식이 없으면 현재 AppDomain 형식을 액세스 할 수 있어야합니다. 내가 이런 식으로 뭔가를 할 필요가 : -

 Type t = Type.GetType("MyGeneratedClass"); 
object x = Activator.CreateInstance(t); 

문제는이 코드에서 t null이되는 끝납니다. 이제 어셈블리가 컴파일되었지만로드되지 않았을 것으로 판단됩니다. 이 어셈블리를 도메인에로드하여 형식 이름을 확인할 수있는 것을 찾을 수 없습니다.

누구든지 나를 계몽시킬 수 있습니까?

답변

6

명시 적으로 불가능합니다.

documentation for Type.GetType 명확하게 상태 : 어셈블리는 GetType을 호출 할 때 디스크에 저장되지 않은

경우,이 메소드는 null를 돌려줍니다. GetType은 일시적인 동적 어셈블리를 인식하지 못합니다. 따라서 GetType을 호출하여 임시 동적 어셈블리에서 형식을 검색하면 null이 반환됩니다.

어셈블리를 일반 어셈블리처럼 작동 시키려면 디스크에 어셈블리를 작성해야합니다.

+0

올바른 솔루션으로 안내하기 때문에 이것을 답으로 선택하십시오. GetType의 이름은 CompileParameters에서 정의 할 수있는 어셈블리 이름으로 quailifed되어야합니다. – AnthonyWJones

+0

@AnthonyWJones : 멋지다! 다행스럽게도 도움이 될 수 있습니다. :-) –

5

GenerateInMemory 속성은 팔러 마술입니다. C# 컴파일러는 프로그램의 메모리에 쓰는 방법을 모릅니다. 위조 된 경우 컴파일러에서 실제로 어셈블리를 TEMP 디렉토리에 쓰도록 요청됩니다. 컴파일 후 FileStream을 사용하여 바이트 [], Assembly.Load (byte [])로 메모리가로드 된 위치부터. Reflector, Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch() 메서드를 사용해보십시오.

어쨌든보기 좋지 않은 파일을 생성하기 때문에 파일을 만들고 AppDomain에로드하면 문제가 해결됩니다.

+0

고마워, 난 GenerateInMemory 제거있어하지만 지금은 어셈블리를로드하는 방법에 붙어있어, 나는'Assembly.LoadFile'을'cr.PathToAssembly'에 사용하고 있습니다. 그러나'GetType'에 대한 호출은 여전히 ​​null을 반환합니다. – AnthonyWJones

+0

전염병처럼 Assembly.LoadFile()을 피하십시오. 항상 LoadFrom()을 사용하십시오. 조립품을 가지고 있음을 주목하십시오. 반사판에서 열어 볼 수 있습니다. 그렇지 않으면 GetType이 작동하지 않는 이유를 추측하기가 어렵습니다. 어쩌면 네임 스페이스를 잊었거나 공개하지 않았을 수 있습니까? 또한 GetTypes()에서 벗어나는 것을 확인하십시오. 다른 AppDomain에로드되도록하려면이 작업을 수행했음을 잊지 마십시오. –

+0

AppDomain 설명을 취소하면 질문에 대해 혼란스러워합니다. 작동 시키면 GenerateInMemory를 다시 true로 설정할 수 있습니다. –