从 byte[] 动态加载程序集
Posted
技术标签:
【中文标题】从 byte[] 动态加载程序集【英文标题】:Dynamically load assembly from byte[] 【发布时间】:2016-10-28 15:04:56 【问题描述】:我需要在运行时多次从内存中加载多个程序集。我还需要在对它们进行一些更改后重新加载这些程序集。
我尝试了标准的 Assembly.Load 方法,它运行良好,直到我意识到当我再次加载相同的程序集时,它在
中出现了两次AppDomain.CurrentDomain.GetAssemblies()
由于多次加载操作,这不是我想要完成的。我知道如果我从磁盘加载 DLL,如果它以不变的形式存在,它将不会加载。
然后我尝试将 DLL 加载到 new AppDomain,但我遇到了依赖问题。
这里是简化的场景:
我有共享的DLL,叫它AssemblyA,它被主应用程序引用。
我还有几个要动态加载的 DLL(称为 AssemblyB...Z)。这些 DLL 还引用了 AssemblyA。
如上所述,我的主应用程序引用了具有抽象类的 AssemblyA,该类具有由主应用程序实现的方法(称为 LoadAssemblies)。此方法用于通过新的 AppDomain 动态加载程序集的其余部分。
这是 LoadAssemblies 的当前代码(我尝试手动加载依赖项):
public override void LoadAssemblies()
AppDomain pluginDomain = AppDomain.CreateDomain("PluginDomain");
foreach (byte[] xmlDLL in listOfDLLS)
Assembly reflection = Assembly.ReflectionOnlyLoad(xmlDLL);
foreach (var dependencies in reflection.GetReferencedAssemblies())
if (dependencies.Name.Equals("AssemblyA"))
Assembly pluginr = Assembly.ReflectionOnlyLoad(AssemblyA);
foreach (var d in pluginr.GetReferencedAssemblies())
pluginDomain.Load(d);
pluginDomain.Load(plugin);
else
pluginDomain.Load(dependencies);
Assembly assembly = pluginDomain.Load(xmlDLL);
上面的代码在线出错
Assembly assembly = pluginDomain.Load(xmlDLL);
这样说:
could not load assembly or one of its dependencies
也尝试了 AssemblyResolver 事件,但它抱怨 Serializable,然后当我使它可序列化时,关于类型。
PS。不幸的是,我无法在磁盘上保存 DLL。
【问题讨论】:
无法从AppDomain
卸载Assemblies
,但您可以卸载AppDomain
。对程序集进行更改后,您是否可以创建一个新的AppDomain
?另外,我假设您已正确地将字节读入缓冲区。
是的,我知道,这就是我想要实现它的方式。字节是 100% 正确的。
【参考方案1】:
我找到了解决方法。解决方法是使用:
pluginDomain.SetData("Assembly", DLLinByteArray);
pluginDomain.DoCallBack(CallbackFunction)
每当我需要在自定义 AppDomain 中做某事时。
例如,对于从字节数组加载 DLL,CallbackFunction 如下所示:
byte[] assemblyToLoad = (byte[])AppDomain.CurrentDomain.GetData("Assembly");
Assembly.Load(assemblyToLoad);
如您所见,我使用 SetData 和 GetData 方法将参数发送到回调方法。
当然,对于从驻留在自定义 AppDomain 中的 DLL 调用方法,我在另一个 CallbackFunction 中执行此操作。
【讨论】:
以上是关于从 byte[] 动态加载程序集的主要内容,如果未能解决你的问题,请参考以下文章