2010-06-04 204 views
3

我到目前爲止與MEF最大的問題是,當我在我的插件加載器包裝中構成部分,當它發現一個導入分辨率加載完全保釋與其中一個組件有關的問題。理想情況下,我希望ComposeParts展示某種「忽略和繼續」行爲,因爲理想的用戶體驗需要加載儘可能多的插件,並在特定插件加載失敗時簡單地記錄事件。我無法在任何地方的文檔中找到關於此的信息。MEF的CompositionContainer.ComposeParts - 加載任何可以解決的問題,並忽略錯誤

如果您對如何解決此問題有任何其他建議,我正在傾聽!

回答

8

維姆的例子有基本的想法,但不要扯在容器上直接我會建議你做一個懶惰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調用中產生。

+0

聽起來不錯。我也會試一試。謝謝! – Dave 2010-06-04 16:31:33

+0

+1 yep,實際上並不需要直接訪問容器。我沒有意識到,儘管現在看起來很明顯。 – 2010-06-06 00:12:13

+0

我還沒有使用懶惰爲你所描述的,但它確實最終幫助我出了我最近的一個問題。現在我完全可以看到它在這種特殊情況下的工作方式了! – Dave 2010-09-16 14:38:34

2

您可以使用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 
     } 
    } 
} 
+0

謝謝,Wim!我會試試這個。 – Dave 2010-06-04 14:26:40

相關問題