MEF ComposeParts. 如何处理插件异常。

5

我在网上搜索了解决方法,但是没有找到任何答案。

在我的C#应用程序中,我使用MEF实现插件模式。一切都运行良好。然而,今天我尝试弄清楚如果插件构造函数由于某些原因抛出异常会发生什么。

为了加载插件,我使用CompositionContainer.ComposeParts。如果其中一个X插件由于某种原因抛出异常,这个方法将失败,并且不会加载任何东西。

有没有办法只捕获单个异常、记录并继续运行?

提前致谢。

2个回答

5

我猜测你调用了CompositionContainer.ComposeParts(this),其中this有一个类似于这样的属性:

[ImportMany]
public IPlugin[] Plugins { get; set; }

这意味着当你调用 ComposeParts 时,所有插件的构造函数都将被调用。另外,你还可以利用惰性加载,它将延迟构造函数的调用,直到实际使用插件时。
[ImportMany]
public Lazy<IPlugin>[] Plugins { get; set; }

如果想要初始化所有插件,你可以像这样编写代码。它会记录异常,但不会阻止其他插件的加载:

public void InitPlugins()
{
    foreach (Lazy<IPlugin> lazyPlugin in Plugins)
    {
        try
        {
            // Call the plugin's constructor
            var plugin = lazyPlugin.Value;

            // Do any other initialization here
        }
        catch (Exception ex)
        {
            // Log exception and continue iteration
        }
    }
}

1
这个答案在理论上看起来不错,但我尝试后发现有问题;我的错误是由于没有提供一个等效的导出,而导入却期望它;我在this类中有多个导入;我不认为推迟构造函数错误会在这种情况下有所帮助——ComposeParts()以“全有或全无”的方式失败(即如果一个导入/导出对存在问题,则不会继续组合好的导入/导出对,而是全部失败!) - joedotnot

0
我发现从ImportMany切换到Import,然后基本上为每个Dll创建一个CompositionContainer + DirectoryCatalog,使我能够轻松地检测和过滤不兼容的插件。
这也没有明显比同时调用多个目录的compose慢。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接