.net - 强大的插件/插件管理的良好架构/库

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

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

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

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

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

最佳答案

您可以使用 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 模型可能提供崩溃保护,您仍需要处理加载项代码中的减速或死锁。异步使用在这里会有所帮助。

关于.net - 强大的插件/插件管理的良好架构/库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5494258/

相关文章:

.net - 使用 BasicHttpBinding 和 Windows 身份验证使用 WCF 服务

c# - 用于创建实时应用程序的 ASP.net/C# 书籍

java - 如何创建可插入的 Java 程序?

c++ - 处理 QPluginLoader::load() 抛出的异常

.net - 如何保护 Windows .net 应用程序中的静态字符串?

c# - 将 COM 对象添加到托管代码

c# - 帮助解决简单的 C# 错误

c# - 我应该检查我的 ASP.NET MVC 应用程序的哪一层成员信息?

asp.net - 企业安全应用程序 block 与 ASP.NET 中的 MembershipProvider 结合使用

javascript - Typo3 showClickmenu 不适用于某些插件提供的项目类型