在运行时多次加载 Roslyn 编译的 DLL

Load with Roslyn compiled DLL at runtime multiple times

目前我正在运行时编译和加载程序集。该程序集始终包含相同的命名空间和 类。当我这样做时 在同一个应用程序实例中多次,在创建程序集中 类 的新实例时,总是会使用 最新的 程序集吗?或者这不能保证?

你正在创造你想要创造的东西。不过,这可能是也可能不是您想要创建的内容。

很可能,您的程序集没有特定名称,而是一个随机的唯一名称 - 在这种情况下,类型完全不同,就 .NET 而言只是偶然相似。来自两个不同编译的类型是完全不相关的,并且不兼容。当您通过动态程序集外部定义的接口访问它们时,这可能会或可能不会成为问题,具体取决于您使用这些类型的方式。

如果添加程序集名称,情况会变得有点复杂。你不能加载同一个程序集两次(旧的不会被新的替换),所以你需要改变版本。然而,同一个程序集的两个版本不能加载到同一个应用程序域中(除了 "fun" 和 AssemblyResolve 等 - 但要做到这一点非常棘手)。第二个程序集将无法加载。

最后,您尝试实例化的 Type 是您 实例化的那个(除非使用绑定重定向,这是额外的乐趣: )。如果您的某些代码保留了之前编译的 Type,那么它将创建的就是它。

如果你的问题是我是否在 AppDomain 中加载程序集

Assembly a1=Assembly.Load(Array of Assembly);

然后使用 roslyn 更改代码,如 class 名称并创建项目的新程序集并再次加载它

Assembly a2 =Assembly.Load(Array of Assembly);

现在 a2 加载到 CurrentDomain 了吗? 我的回答是 .a1 现在不在 CurrentDomain 中。

你可以测试一下。

因此,要使用新程序集,您必须使用以下解决方案。

您需要在另一个 AppDomain 中加载此程序集,每次您都可以卸载此 AppDomain 并重新创建它并再次加载程序集

首先创建一个 class,CurrentDomain 会将其实例加载到另一个 AppDomain class 的这个对象必须加载您的程序集及其对第二个 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);