Не удается получить доступ к CodeBase из динамически сгенерированной сборки - PullRequest
4 голосов
/ 11 апреля 2010

Я пытаюсь создать сборку динамически в .Net. Однако я не могу понять, как заставить свойство 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 ]

3 голосов
/ 11 апреля 2010

Я думаю, что причиной исключения является то, что 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
1 голос
/ 11 апреля 2010

Является ли сборка Location действительной? Не могли бы вы раскошелиться на NUnit и использовать его вместо того, чтобы ссылаться на повреждение: P

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

...