开发者

Can't access CodeBase from a dynamically generated assembly

I'm trying to create an assembly dynamically in .Net. I can't seem to figure out how to get the CodeBase property to return a value, however. Here's an example:

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开发者_StackOverflow中文版, 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()

Can anyone see what I'm doing wrong?

Explanation: I'm trying to extend NUnit with an addin that generates test methods at runtime. It does this by taking an array of Action delegates. Unfortunately, Reflection is baked pretty deep into the framework, so I have had to emit classes with a method for each Action delegate. This works fine when I'm using the NUnitTestMethod classes only, but when I use the NUnitTestFixture, it fails because it tries to read the CodeBase from the assembly. I didn't want to create a physical assembly, but this project has been one compromise after another.


I think the exception cause is that CodeBase is meaningless on dynamic assembly. From MSDN:

The location of the assembly as specified originally

If you'll reload the assembly it won't throw the exception:

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


Is the Assembly's Location valid? Could you fork NUnit and use that instead given your reference to being damaged :P

I've spent some hours being subjected to NUnit's 'extensibility' story and can't imagine ever choosing it over xUnit.net - but I guess the decider of that will be how many tests you have...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜