Загрузка скомпилированной сборки InMemory в текущий домен

Я использую CSharpCodeProvider собрать сборку, и у меня есть CompileParametersGenerateInMemory свойство установлено в true потому что я не хочу создавать физический файл.

После компиляции я могу взять CompilerResults и сделать что-то вроде этого:

 object x = cr.CompiledAssembly.CreateInstance("MyGeneratedClass");
 Console.WriteLine(x);

Я получаю ожидаемый результат, CreateInstance работал.

Однако мне нужно иметь возможность доступа к типам в текущем AppDomain без таких знаний о сборке. Мне нужно сделать что-то вроде этого:

 Type t = Type.GetType("MyGeneratedClass");
 object x = Activator.CreateInstance(t);

Проблема в этом коде t заканчивается нулем. Теперь я подозреваю, что хотя сборка скомпилирована, она не загружается. Я не могу найти, чтобы загрузить эту сборку в домен, чтобы можно было разрешить имена его типов.

Кто-нибудь может просветить меня?

2 ответа

Решение

Боюсь, это явно невозможно.

В документации для Type.GetType четко сказано:

Если сборка не была сохранена на диск при вызове GetType, метод возвращает значение NULL. GetType не понимает переходные динамические сборки; следовательно, вызов GetType для извлечения типа во временной динамической сборке возвращает null.

Вам нужно будет записать сборку на диск, если вы хотите, чтобы она работала так же, как любая обычная сборка.

Свойство GenerateInMemory - хитрый прием. Компилятор C# не знает, как записывать в память вашей программы. Это подделка, компилятору предлагается на самом деле записать сборку в каталог TEMP. Откуда он загружается в память после успешной компиляции с FileStream в byte[], затем Assembly.Load(byte[]). Посмотрите с помощью метода Reflector, Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch().

Так как он в любом случае создает файл, просто не очень заметный, решите свою проблему, просто позволив ему создать файл и загрузив его в AppDomain.

Другие вопросы по тегам