2012-11-20 1 views
4

Я хочу динамически создавать сборки в тестах интеграции для тестирования некоторых классов манипуляции с сборками. Если я использую следующий код для создания тестирования сборок:Исключение при динамическом создании сборок с использованием DefineDynamicAssembly при нетоке AppDomain

var domain = AppDomain.CurrentDomain; 

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

builder.Save(fileName); 

тогда все работает нормально, сборки создаются в нужном месте, но как часть этого они также загружены в текущий AppDomain, что я не Не хочу.

Так что, хотя о создании сборок с помощью отдельного AppDomain:

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

... 

Но выполнение кода генерирует исключение на линии var builder = domain.DefineDynamicAssembly(...);:

System.Runtime.Serialization.SerializationException: Тип 'System.Reflection.Emit.AssemblyBuilder' в сборке 'mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089' не помечен как сериализуемый.

Я понятия не имею, как это связано с вызовом DefineDynamicAssembly на внеоборотный AppDomain. Все, что я нахожу в Интернете, в основном касается выполнения сборок в отдельных доменах. Возможно, то, что я пытаюсь сделать здесь, слишком специфично, слишком продвинуто или даже не рекомендуется вообще, но это позволило бы мне проверить весь наш код манипуляции с сборкой.

Может кто-нибудь указать мне в правильном направлении?

+0

Не могли бы вы опубликовать фактический код, который выдает это исключение? И почему именно вы не хотите загружать его в текущий AppDomain? Если вы беспокоитесь о памяти, вы можете попробовать вместо этого «AssemblyBuilderAccess.RunAndCollect». – svick

+0

@svick Исключение возникает в 'var builder = domain.DefineDynamicAssembly (...);' line, я обновил вопрос. – famousgarkin

+0

@svick Мне не нужны «поддельные» сборки, которые не разделяются между тестами, чтобы попасть в глобальную область. Хотя на данный момент это в основном по причинам чистоты, некоторые из этих сборок, вероятно, будут содержать некоторый код позже, что может быть проблемой. – famousgarkin

ответ

1

Я получил его, выполнив код в другом AppDomain, например 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); 
}); 

Примечание Вы должны указать ApplicationBase на AppDomainSetup, чтобы найти делегат в другой AppDomain.