【问题标题】:Good Architecture/Library For Robust Plugin/Addon Management强大的插件/插件管理的良好架构/库
【发布时间】:2011-07-26 12:58:44
【问题描述】:

我们有一个应用程序,作为它的要求之一,它将采用任意 3rd 方插件,加载它们,并与我们自己开发的应用程序一起运行它们的 UI。我们一直在将这些 3rd 方插件加载到他们自己的 AppDomain 中以进行隔离,并且一切正常。

直到其中一个插件因未处理的异常而崩溃。在这种情况下,整个应用程序都会出现故障,即使真正受到影响的只是我们的“额外”工具窗口之一。

理想情况下,我们希望有某种方法来处理“未处理”异常,卸载损坏的 AppDomain,然后重新加载它。问题是我们找不到机制在未处理异常的事件处理程序中,我们可以将异常标记为“已处理”。此外,由于插件有自己的 UI 组件和自己的用户交互集,因此很难将我们与插件的交互“包装”在 try/catch/finally 块中。

是否有任何框架/编程库/模式可以帮助解决这个问题?我们可以很好地做插件; 我们需要帮助的是在不同 AppDomain 中的代码意外失败时保持应用程序的运行。

【问题讨论】:

  • 值得重申的是,这里的主要目标是在 AppDomain 崩溃中幸存下来。

标签: .net architecture plugins error-handling crash-recovery


【解决方案1】:

您可以使用System.Addin 框架(有时称为MAF),正确设置有点麻烦,但它旨在提供隔离(崩溃保护)。 System.Addin 基于远程处理。使用此框架,您可以让插件以有限的权限运行在同一进程中,或在另一个应用程序域中,甚至在另一个进程中。

如果您需要全面的崩溃保护,您可能需要使用进程分离选项。不过,它可能会以性能为代价。

您可以使用此代码在不同的应用程序域中加载插件:

AppDomain addInDomain = AppDomain.CreateDomain("addin domain");

// addInDomain.PermissionSet = ...
AddInEnvironment env = new AddInEnvironment(addInDomain);

// Activate the add-in
IHostView addinInstance = addinToken.Activate<IHostView>(env);

Console.WriteLine(addinInstance.DoSomething());

AppDomain.Unload(addInDomain);

如果要将插件加载到另一个进程中,以实现完全隔离:

AddInProcess process = new AddInProcess();
process.Start();

// Activate the add-in
IHostView addinInstance = addinToken.Activate<IHostView>(process, AddInSecurityLevel.Internet);

try 
{
    // use a catch block, prevent exceptions from the addin crashing the main app
    Console.WriteLine(addinInstance.DoSomething());
} 
catch (Exception e)
{
    Console.WriteLine(e);
}

process.Shutdown();

blog 很好地描述了设置。

可以将 System.Addin 与 MEF 结合使用,这些是免费的工具包,请参阅 this article

请注意,System.Addin 模型可能提供崩溃保护,您仍然需要处理插件代码中的减速或死锁。异步使用在这里会有所帮助。

【讨论】:

    【解决方案2】:

    我认为这是不可能的。我的理解是,即使你处理了AppDomain.UnhandledException 事件,应用程序仍然会终止。你能做的最好的事情就是处理异常,记录你能做的,保存你能做的状态,然后优雅地终止。

    【讨论】:

    • 这符合我们的实验,但我看到很多人声称在单独的 appDomain 中运行提供了崩溃保护/隔离。要么每个人都错了,要么我们错过了什么。我希望是后者。
    • 根据我的经验,唯一真正的隔离是创建一个单独的进程。不过,这听起来不像你们的选择。
    【解决方案3】:

    【讨论】:

    • MEF 是否保护您免受插件崩溃的影响?
    【解决方案4】:

    听起来您想要类似于 OSGi for Java 的东西——Is MEF OSGi for .NET? 看起来可能符合要求。

    【讨论】:

    • MEF 是否保护您免受插件崩溃的影响?
    • MEF 并不能从本质上保护您免受插件崩溃的影响,但是您可以在单独的应用程序域中运行它们。信用到期:stackoverflow.com/questions/835182/…
    • 我们尝试在不同的应用程序域中运行代码,但仍然有问题;有关详细信息,请参阅问题。也许我们缺少实现这种行为的技术或配置?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 2023-03-24
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多