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

min*_*ina 2 .net c# appdomain assembly-resolution .net-assembly

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

首先,我尝试创建一个新的AppDomain:

AppDomain domain = AppDomain.CreateDomain("PluginDomain");
Run Code Online (Sandbox Code Playgroud)

由于我的主要问题是解析我正在尝试加载的程序集,我试图挂钩AssemblyResolve事件:

domain.AssemblyResolve += new ResolveEventHandler(this.OnAssemblyResolve);
Run Code Online (Sandbox Code Playgroud)

但是,我得到一个关于序列化的错误(即这个类).

我已成功加载一个汇编文件,它恰好位于BaseDirectory中,只需使用:

domain.Load("Assembly1");
Run Code Online (Sandbox Code Playgroud)

但有问题的程序集位于BaseDirectory的两个子目录中,即.BaseDirectory\dir1\dir2\Assembly2.dll - 当使用带有字符串程序集名称的domain.Load()(将PrivateBinPath安装到正确的子目录位置)时以及使用带有程序集字节的domain.Load()时,我得到FileNotFoundException (来自File.ReadAllBytes()).

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

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

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

Ňuf*_*Ňuf 5

Assembly.AssemblyResolve的事件处理程序必须位于应加载此程序集的同一AppDomain中.这是因为此处理程序必须返回对Assembly实例的引用,但是一旦引用了程序集,它就会自动加载,因此程序集将在两个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");
Run Code Online (Sandbox Code Playgroud)