Exception while dynamically creating assemblies us

2019-06-22 15:19发布

问题:

I want to dynamically create assemblies in the integration tests for the purpose of testing some assembly manipulation classes. If I use the following code to create the testing assemblies:

var domain = AppDomain.CurrentDomain;

var builder = domain.DefineDynamicAssembly(
    new AssemblyName(assemblyName),
    AssemblyBuilderAccess.Save,
    directory);

builder.Save(fileName);

then everything runs ok, the assemblies are created in the required location, but as part of this they are also loaded to the current AppDomain, which I don't want.

So I though about creating the assemblies using the separate AppDomain:

var domain = AppDomain.CreateDomain("Test");

...

But running the code throws an exception at the line var builder = domain.DefineDynamicAssembly(...);:

System.Runtime.Serialization.SerializationException: Type 'System.Reflection.Emit.AssemblyBuilder' in assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.

I have no clue how this relates to calling DefineDynamicAssembly on a non-current AppDomain. All I find online is mostly about executing assemblies in separate domains. Perhaps what I'm trying to do here is just too specific, too advanced or even not recommended at all, but it would enable me to test all our assembly manipulation code.

Can someone please point me in the right direction?

回答1:

I got it working by executing the code in the other AppDomain, like suggested.

var appdomain = AppDomain.CreateDomain("CreatingAssembliesAndExecutingTests", null,
   new AppDomainSetup { ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase });

appdomain.DoCallBack(() =>
{
   var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("temp"), AssemblyBuilderAccess.Run);
   var module = assembly.DefineDynamicModule("DynModule");
   var typeBuilder = module.DefineType("MyTempClass", TypeAttributes.Public | TypeAttributes.Serializable);
});

Remark you have to specify the ApplicationBase on the AppDomainSetup in order to find the delegate in the other AppDomain.