2010-04-10 8 views
4

.Net에서 동적으로 어셈블리를 만들려고합니다. 그러나 CodeBase 속성에서 값을 반환하는 방법을 알아낼 수 없습니다. 다음은 그 예입니다.동적으로 생성 된 어셈블리에서 CodeBase에 액세스 할 수 없습니다.

var assemblyName = new AssemblyName 
         { 
          Name = "Whatever", 
          CodeBase = Directory.GetCurrentDirectory() 
         }; 
var assemblyBuilder = AppDomain.CurrentDomain 
    .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); 
var moduleBuilder = assemblyBuilder.DefineDynamicModule("WhateverModule", "Whatever.dll"); 
var typeBuilder = moduleBuilder.DefineType("WhateverType", TypeAttributes.Public); 
var type = typeBuilder.CreateType(); 
assemblyBuilder.Save("Whatever.dll"); 
var codeBase = type.Assembly.CodeBase; // throws the below exception 

System.NotSupportedException was unhandled 
    Message=The invoked member is not supported in a dynamic assembly. 
    Source=mscorlib 
    StackTrace: 
     at System.Reflection.Emit.InternalAssemblyBuilder.get_CodeBase() 
     at Stupid.Program.Main(String[] args) in C:\Users\Walking Disaster\Documents\Visual Studio 10\Projects\Lingual.Proxy\Stupid\Program.cs:line 25 
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 

내가 잘못하고있는 것을 누구든지 볼 수 있습니까?

설명 런타임시 테스트 메소드를 생성하는 addin으로 NUnit을 확장하려고합니다. 이것은 액션 델리게이트의 배열을 취함으로써이를 수행합니다. 안타깝게도 Reflection은 프레임 워크 깊숙이 구워져 있으므로 각 Action Delegate에 대한 메서드로 클래스를 내 보내야했습니다. NUnitTestMethod 클래스를 사용할 때만 제대로 작동하지만 NUnitTestFixture를 사용할 때 어셈블리에서 CodeBase를 읽으므로 실패합니다. 나는 물리적 인 어셈블리를 만들고 싶지 않았지만,이 프로젝트는 다른 프로젝트와 절충안이었습니다.

답변

2

예외 원인은 동적 어셈블리에서 CodeBase가 의미가 없다고 생각합니다. MSDN에서 :

당신이 어셈블리를 다시로드합니다 경우 예외가 발생하지 않습니다

원래 지정된 어셈블리의 위치 :

var assemblyName = new AssemblyName 
         { 
          Name = "Whatever", 
          CodeBase = Directory.GetCurrentDirectory() 
         }; 
var assemblyBuilder = AppDomain.CurrentDomain 
    .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); 
var moduleBuilder = assemblyBuilder.DefineDynamicModule(
    "WhateverModule", "Whatever.dll"); 
var typeBuilder = 
       moduleBuilder.DefineType("WhateverType", TypeAttributes.Public); 
var type = typeBuilder.CreateType(); 
assemblyBuilder.Save("Whatever.dll"); 

var assembly = Assembly.LoadFrom("Whatever.dll"); 
var codeBase = assembly.CodeBase; // this won't throw exception 
+0

나는 이것을 두려워했다. 나는이 일을해야만 할 수도있다. 그런 다음 리플렉션에 대한 의존도가 심한 데미지를 줄이기 위해 NUnit을 더 깊이 파헤쳐 라. –

1

이 국회 Location 유효한가를 ? 너는 NUnit을 포크로 쓰고 그 대신에 너의 레퍼런스를 손상시킨 것에 사용 해줄 수 있니? P

나는 NUnit의 '확장 성'이야기에 복종하는 데 시간을 썼으며 xUnit.net에서 그것을 선택하는 것을 상상할 수는 없다. 그것의 결정자는 얼마나 많은 검사를받을 것인가 ...

+1

나는 너와 함께있다. NUnit이 리플렉션을 통해 모든 테스트 메타 데이터를 선택했다고 생각하지 않습니다. 불행히도, 이것은 기존 프로젝트를위한 것이며 우리는 이미 7K + NUnit 테스트를 가지고 있습니다. xUnit을 사용하면 NUnit 테스트를 수행 할 수 있지만이 작업을 프로젝트의 완료 시점으로 전환하는 것이 바람직하지는 않습니다. 나는 xUnit에 내 작업을 포팅하는 것을보고 있는데, 다음 프로젝트를 위해. –

+1

아마 맞는 것 같지는 않지만 RunWithNUnitAttribute [xunit 러너를 통해 NUnit 테스트를 실행할 수 있습니다]를 보았습니다. Havent는 그 주위에 예제를 보았지만 xunit의 샘플이 얼마나 깨끗하고 간략한 지 (샘플을 다운로드하고 NUnitRunnerAcceptanceTests를 찾으십시오) 놀랄 것입니다. (네, 매우 긴 발사!) –

관련 문제