В настоящее время я собираю и загружаю сборку во время выполнения. Сборка всегда содержит те же пространства имен и классы. Когда я делаю это несколько раз в том же экземпляре приложения, всегда ли используется сборка при создании новых экземпляров классов, находящихся в сборке? Или это не гарантировано?Загрузка с Roslyn скомпилированной DLL во время выполнения несколько раз
ответ
Вы создаете именно то, что пытаетесь создать. Это может быть или не быть тем, что вы хотите, чтобы создать.
Скорее всего, ваши сборки не имеют определенного имени, а скорее рандомизированное уникальное имя - в этом случае типы совершенно разные и только случайно похожи на .NET. Типы из двух разных компиляций полностью не связаны и несовместимы. Это может быть или не быть проблемой, когда вы обращаетесь к ним через интерфейс, определенный вне динамической сборки, в зависимости от того, как именно вы используете типы.
Если вы добавите имя сборки, ситуация станет немного сложнее. Вы не можете загрузить одну и ту же сборку дважды (старая не заменяется новой), поэтому вам нужно изменить версию. Однако две версии одной и той же сборки не могут быть загружены в одном домене приложения (кроме случаев, когда вы выполняете «забаву» с AssemblyResolve
и т. Д., Но это довольно сложно, чтобы получить право). Вторая сборка просто не загрузится.
В конце концов, Type
вы пытаетесь создать экземпляр, который вы сделать Instantiate (за исключением использования обязательных перенаправлений, которые бонус весело: P). Если какой-то фрагмент кода держится на Type
из предыдущей компиляции, это то, что он собирается создать.
Если ваш вопрос, если я загрузить сборку в AppDomain
Assembly a1=Assembly.Load(Array of Assembly);
А затем изменить код с Рослин, как имя класса и создать новую сборку вашего проекта и загрузить его снова
Assembly a2 =Assembly.Load(Array of Assembly);
сейчас a2 загружается в CurrentDomain? Мой ответ: нет .a1 теперь находится в CurrentDomain.
Вы можете проверить его.
Для работы с новой сборкой вы должны использовать ниже решение.
Вы должны загрузить эту сборку в другой AppDomain и каждый раз, когда вы можете выгрузить эту AppDomain и создать его снова и сборку нагрузки снова
Сначала нужно создать класс, который CurrentDomain загрузит экземпляр, что на другой AppDomain этого объекта из класс должен загрузить вашу сборку и ее зависимости для второго AppDomain.
// you can create this class in another project and
// make assembly .because you need a copy of it in
//folder that you set for ApplicationBase of second AppDomain
public class AssemblyLoader : MarshallByRefObject
{
AssemblyLoader()
{
AppDomain.CurrentAppDomain.AssemblyResolve += LoaddependencyOfAssembly;
}
public void LoaddependencyOfAssembly(object sender,)
{
//load depdency of your assembly here
// if you has replaced those dependencies to folder that you set for ApplicationBase of second AppDomain doesn't need do anything here
}
public Assembly asm {get;set;}
public void LoadAssembly(MemoryStream ms)
{
asm= Assembly.Load(ms.ToArray());
}
}
в котором вы хотите загрузить Ассамблее
AppDomainSetup s=new AppDomainSetup(){ApplicationBase="anotherFolderFromYourAppBinFoldr};
AppDomain ad= AppDomain.CreateDomain("name",AppDomain.CurrentDomain.Evidence,s);
Type t = typeof(AssemblyLoader);
AssemblyLoader al = (AssemblyLoader) ad.CreateInstanceAndUnwrap(t.Assembly.FullName,t.FullName);
// load assembly here by Stream or fileName
al.LoadAssembly(ms);
// now assembly loaded on ad
// you can do your work with this assembly by al
// for example create a method in AssemblyLoader to
// get il of methods with name of them
// Below IL is in CurrentDomain
//when compiler goes to GetIlAsByteArray you are in second AppDomain
byte[] IL = al.GetILAsByteArray("NameOfMethod");
//And unload second AppDomain
AppDomain.Unload(ad);
Спасибо за ваш ответ. Я никогда не работал с разными AppDomains. Это позволяет легко общаться между основным AppDomain и вновь созданным? Спасибо – BendEg
Я сказал в своем ответе. Вы можете, например, получить il методов в сборке и вернуть его в первый AppDomain.I отредактирую ответ – mohsen
Спасибо за этот подробный ответ и работу. Я попробую это и вернусь к вам. +2 Если бы я мог ... – BendEg
Спасибо за ваш ответ. Поэтому я не должен беспокоиться, потому что в этом конкретном случае я не использую экземпляры типов, которые определены в * старой * сборке. Большое спасибо! Да, у них также нет имени, потому что я уже столкнулся с проблемами при предоставлении им имен :) – BendEg
@BendEg Yup, это должно работать нормально.Обратите внимание, что старые сборки не очищаются, поэтому, если вы часто делаете компиляцию в одном и том же процессе, вы можете загрузить их в другой AppDomain (вы можете выгрузить домен, когда он больше не будет полезен). – Luaan