.net 插件AppDomains解决方案

.net 插件AppDomains解决方案,.net,plugins,appdomain,appdomainsetup,.net,Plugins,Appdomain,Appdomainsetup,在处理自己子目录中的插件程序集时,有一个众所周知的问题,即一旦这些程序集尝试从其子目录加载各自的依赖项,它们就无法加载。解决方案是加载AppDomains中的插件,这些插件在初始化时在其AppDomainSetup对象中设置了PrivateBinPath。然而,这会导致编组/跨AppDomain通信方面的其他困难,特别是如果插件应该提供一些GUI的话 当安全方面的优先级较低时(非关键实用程序应用程序,错误插件导致崩溃时不会出现严重问题),我有以下想法:在应用程序启动时,应该搜索所有插件目录,并创

在处理自己子目录中的插件程序集时,有一个众所周知的问题,即一旦这些程序集尝试从其子目录加载各自的依赖项,它们就无法加载。解决方案是加载AppDomains中的插件,这些插件在初始化时在其
AppDomainSetup
对象中设置了
PrivateBinPath
。然而,这会导致编组/跨AppDomain通信方面的其他困难,特别是如果插件应该提供一些GUI的话

当安全方面的优先级较低时(非关键实用程序应用程序,错误插件导致崩溃时不会出现严重问题),我有以下想法:在应用程序启动时,应该搜索所有插件目录,并创建一个新的AppDomain,在其bin路径中包含这些目录。然后,整个应用程序及其GUI与所有插件一起在新的AppDomain中运行


在特定情况下,是否有任何理由避免这种解决方案?或者,可能有什么原因导致该解决方案不可行?

考虑到您所描述的场景,我不知道与您的第二个域提案相关的任何问题。但是,您也可以通过在addins子目录中搜索自己并使用从那里加载程序集来研究在初始域上处理程序集加载失败的可能性

可能的设置示例,其中必须实现
FindAssemblyByName
以搜索所有可能的位置:

static void Main(string[] args)
{
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

    // ...
}

static Assembly CurrentDomain_AssemblyResolve(
    object sender, 
    ResolveEventArgs e)
{
    var assemblyName = new AssemblyName(e.Name);

    string assemblyFilePath = FindAssemblyByName(assemblyName);

    if (string.IsNullOrEmpty(assemblyFilePath))
        return null;

    return Assembly.LoadFrom(assemblyFilePath);
}

我认为,如果您的主UI与插件运行在同一AppDomain中,那么如果插件崩溃,主UI可能会崩溃。您使用的是加载项框架还是“RYO”@IAbstract:即使在另一个AppDomain中运行,插件崩溃是否也会导致主UI崩溃?毕竟,插件中抛出的任何异常都会跨AppDomain边界进行编组,并使主应用程序退出,除非我处理这些异常。在我的特殊情况下,这是RYO-我已经研究了Addin框架并阅读了许多关于它的文章,但它们都提到了核心应用程序和插件之间的极简接口,而不是我需要传输的复杂和深度嵌套的对象层次结构。这只适用于托管程序集吗?更具体地说,当我在子目录中手动找到插件程序集时,会自动发现同一子目录中的非托管库吗?
assembly.LoadFrom
允许找到并加载对该路径的进一步依赖,因为路径信息由上下文维护。但是,对于混合中的非托管程序集,我不愿意给您任何确定性。我已经对此进行了进一步的阅读,并做了一些测试。如果非托管库与使用
LoadFrom
加载的程序集位于同一目录中,则似乎不仅可以找到托管库,还可以找到非托管库。但是,在中读取时,
LoadFrom
似乎专门将程序集加载到所谓的LoadFrom上下文中,而由于各种原因,加载上下文更可取。另一方面,我看不到从自定义位置将程序集加载到该加载上下文中的任何方法。