2010-04-10 1 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() 

Может ли кто-нибудь увидеть, что я делаю неправильно?

Пояснение: Я пытаюсь расширить NUnit с помощью добавления, которое генерирует методы тестирования во время выполнения. Он делает это, принимая массив делегатов Action. К сожалению, Reflection довольно сильно испечен в структуре, поэтому мне пришлось издать классы с помощью метода для каждого делегата Action. Это отлично работает, когда я использую только классы 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, чтобы попытаться ограничить ущерб, который вызывает их большая зависимость от Reflection. –

1

ли Ассамблеи Location действительными ? Могли бы вы переделать NUnit и использовать это вместо того, чтобы дать вам ссылку на повреждение: P

Я потратил несколько часов на то, чтобы рассказывать историю о расширении NUnit и не могу себе представить, когда-либо выбирал ее на xUnit.net - но я думаю решающим будет то, сколько тестов у вас есть ...

+1

Я с тобой. Я не могу поверить, что NUnit решил получить все тестовые метаданные через отражение. К сожалению, это для существующего проекта, и у нас уже есть тесты 7K + NUnit. Я знаю, что xUnit позволяет запускать тесты NUnit, но есть препятствие для переключения на близкое к завершению проекта. Я смотрю на перенос моей работы на xUnit, однако, для следующего проекта. –

+1

Я думаю, это маловероятно, что он подойдет, но вы посмотрели RunWithNUnitAttribute [который позволяет запускать тесты NUnit через бегун xunit]. Хавент видел какие-либо примеры вокруг него, но вы были бы удивлены, насколько чисты и короткие образцы в xunit (загружать образцы и искать NUnitRunnerAcceptanceTests)? (Да, очень длинный выстрел!) –