我到目前爲止與MEF最大的問題是,當我在我的插件加載器包裝中構成部分,當它發現一個導入分辨率加載完全保釋與其中一個組件有關的問題。理想情況下,我希望ComposeParts展示某種「忽略和繼續」行爲,因爲理想的用戶體驗需要加載儘可能多的插件,並在特定插件加載失敗時簡單地記錄事件。我無法在任何地方的文檔中找到關於此的信息。MEF的CompositionContainer.ComposeParts - 加載任何可以解決的問題,並忽略錯誤
如果您對如何解決此問題有任何其他建議,我正在傾聽!
我到目前爲止與MEF最大的問題是,當我在我的插件加載器包裝中構成部分,當它發現一個導入分辨率加載完全保釋與其中一個組件有關的問題。理想情況下,我希望ComposeParts展示某種「忽略和繼續」行爲,因爲理想的用戶體驗需要加載儘可能多的插件,並在特定插件加載失敗時簡單地記錄事件。我無法在任何地方的文檔中找到關於此的信息。MEF的CompositionContainer.ComposeParts - 加載任何可以解決的問題,並忽略錯誤
如果您對如何解決此問題有任何其他建議,我正在傾聽!
維姆的例子有基本的想法,但不要扯在容器上直接我會建議你做一個懶惰ImportMany像例如:
[Export]
public class MyApplication
{
[ImportMany(typeof(IPlugin))]
public IEnumerable<Lazy<IPlugin>> Plugins { get; set; }
}
然後你就可以初始化插件逐一搭上他們的任何錯誤,如:
void InitializePlugins()
{
foreach (Lazy<IPlugin> plugin in Plugins)
{
try
{
plugin.Value.Initialize();
}
catch (CompositionException e)
{
// Handle the error accordingly
}
}
}
實際的插件將無法創建ü但是,如果插件在導入的構造函數或屬性設置器中存在錯誤,那麼您第一次使用.Value時會發生錯誤。另外請注意,如果插件做錯了,我會捕獲CompositionValue,它會從.Value調用中產生。
您可以使用AllowDefault
參數。如果在導入時將其設置爲true,則會導致相關性爲null
,如果沒有可用部件可以滿足導入。
public class MyComponent
{
[Import(AllowDefault=true)]
public IMyDependency MyDependency { get; set; }
}
要加載所有可用的插件,但忽略那些不能因爲缺少零件的加載,[ImportMany]
就已經做你想做的默認:
[Export]
public class MyApplication
{
[ImportMany(typeof(IPlugin))]
public IEnumerable<IPlugin> Plugins { get; set; }
}
注意的是,上述技術只消除組成錯誤這是由缺少的部分造成的。如果一個零件及其導入實際上是可用的,但它在構造函數被調用時會引發意外的異常,那麼您仍然會得到一個異常。忽略這樣的問題,這不是組成有關,你可以直接調用容器是這樣的:
IEnumerable<IPlugin> GetPluginsFromContainer(CompositionContainer container)
{
foreach (Lazy<IPlugin> pluginExport in container.GetExports<IPlugin>())
{
try
{
yield return pluginExport.Value;
}
catch (Exception e)
{
// report failure to instantiate plugin somewhere
}
}
}
謝謝,Wim!我會試試這個。 – Dave 2010-06-04 14:26:40
聽起來不錯。我也會試一試。謝謝! – Dave 2010-06-04 16:31:33
+1 yep,實際上並不需要直接訪問容器。我沒有意識到,儘管現在看起來很明顯。 – 2010-06-06 00:12:13
我還沒有使用懶惰爲你所描述的,但它確實最終幫助我出了我最近的一個問題。現在我完全可以看到它在這種特殊情況下的工作方式了! –
Dave
2010-09-16 14:38:34