2016-05-10 5 views
1

В настоящее время я собираю и загружаю сборку во время выполнения. Сборка всегда содержит те же пространства имен и классы. Когда я делаю это несколько раз в том же экземпляре приложения, всегда ли используется сборка при создании новых экземпляров классов, находящихся в сборке? Или это не гарантировано?Загрузка с Roslyn скомпилированной DLL во время выполнения несколько раз

ответ

1

Вы создаете именно то, что пытаетесь создать. Это может быть или не быть тем, что вы хотите, чтобы создать.

Скорее всего, ваши сборки не имеют определенного имени, а скорее рандомизированное уникальное имя - в этом случае типы совершенно разные и только случайно похожи на .NET. Типы из двух разных компиляций полностью не связаны и несовместимы. Это может быть или не быть проблемой, когда вы обращаетесь к ним через интерфейс, определенный вне динамической сборки, в зависимости от того, как именно вы используете типы.

Если вы добавите имя сборки, ситуация станет немного сложнее. Вы не можете загрузить одну и ту же сборку дважды (старая не заменяется новой), поэтому вам нужно изменить версию. Однако две версии одной и той же сборки не могут быть загружены в одном домене приложения (кроме случаев, когда вы выполняете «забаву» с AssemblyResolve и т. Д., Но это довольно сложно, чтобы получить право). Вторая сборка просто не загрузится.

В конце концов, Type вы пытаетесь создать экземпляр, который вы сделать Instantiate (за исключением использования обязательных перенаправлений, которые бонус весело: P). Если какой-то фрагмент кода держится на Type из предыдущей компиляции, это то, что он собирается создать.

+0

Спасибо за ваш ответ. Поэтому я не должен беспокоиться, потому что в этом конкретном случае я не использую экземпляры типов, которые определены в * старой * сборке. Большое спасибо! Да, у них также нет имени, потому что я уже столкнулся с проблемами при предоставлении им имен :) – BendEg

+1

@BendEg Yup, это должно работать нормально.Обратите внимание, что старые сборки не очищаются, поэтому, если вы часто делаете компиляцию в одном и том же процессе, вы можете загрузить их в другой AppDomain (вы можете выгрузить домен, когда он больше не будет полезен). – Luaan

1

Если ваш вопрос, если я загрузить сборку в 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); 
+0

Спасибо за ваш ответ. Я никогда не работал с разными AppDomains. Это позволяет легко общаться между основным AppDomain и вновь созданным? Спасибо – BendEg

+0

Я сказал в своем ответе. Вы можете, например, получить il методов в сборке и вернуть его в первый AppDomain.I отредактирую ответ – mohsen

+0

Спасибо за этот подробный ответ и работу. Я попробую это и вернусь к вам. +2 Если бы я мог ... – BendEg