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...
精彩评论