将程序集加载到新的 AppDomain 以进行静态类/方法调用时出现问题

本文关键字:方法 静态类 调用 问题 加载 程序集 AppDomain | 更新日期: 2023-09-27 18:31:54

我在通过 C# 执行 .NET 程序集时遇到了一些主要问题。我想从静态类调用静态方法(Main)。我让它在当前域中工作,但显然我无法从那里卸载程序集。

首先,我尝试创建一个新的应用程序域:

AppDomain domain = AppDomain.CreateDomain("PluginDomain");

由于我的主要问题是解析我尝试加载的程序集,因此我尝试挂钩AssemblySolve事件:

domain.AssemblyResolve += new ResolveEventHandler(this.OnAssemblyResolve);

但是,我收到有关使用此序列化的错误(即此类)。

我已经成功加载了一个程序集文件,该文件恰好位于 BaseDirectory 中,只需使用:

domain.Load("Assembly1");

但是有问题的程序集位于 BaseDirectory 的两个子目录中,即。BaseDirectory''dir1''dir2''Assembly2.dll - 我在使用domain时得到一个FileNotFoundException。Load() 带有字符串程序集名称(将 PrivateBinPath 设置为正确的子目录位置),并且使用域时也是如此。Load() 与程序集字节(来自 File.ReadAllBytes())。

我知道 AppDomain.Load() 已被弃用,但考虑到我不想强制包含静态方法的类是非静态和可实例化的,这对我来说似乎是唯一可用的方法。

无论如何,我该怎么做才能确保程序集文件正确加载到新的 AppDomain 中?

的主要目标是从程序集动态执行一个方法,该方法可以调用我自己的程序,但在必要时也必须完全卸载程序集。它在某种程度上是一个插件系统。

将程序集加载到新的 AppDomain 以进行静态类/方法调用时出现问题

Assembly.AssemblyResolve 的事件处理程序必须位于应加载此程序集的同一 AppDomain 中。这是因为此处理程序必须返回对程序集实例的引用,但是一旦您引用了程序集,它就会自动加载,以便程序集将在两个 AppDomain 中加载。

我建议您在与主应用程序相同的目录中创建小型单独的程序集。此程序集将仅包含一个派生自 MarshalByRefObject 的帮助程序类,该类可以处理程序集解析/加载,并且可以提供调用所需的插件静态方法。将此程序集加载到要加载插件的每个 AppDomain 中,创建 hepler 类的实例并调用它。

public class HelperClass: MarshalByRefObject
{
    public void LoadPlugin(string PluginFileName)
    {
        //Load plugin assembly or register handler for Assembly.AssemblyResolve
        //AppDomain.CurrentDomain.Load()
        //AppDomain.CurrentDomain.AssemblyResolve += ...
        //Call plugin's static method
    }
}

AppDomain domain = AppDomain.CreateDomain("PluginDomain");
domain.Load("plugin_helper.dll");
HelperClass helper = (HelperClass)domain.CreateInstanceAndUnwrap("plugin_helper.dll", "HelperClass");
helper.LoadPlugin("plugin1.dll");