2008-11-05 56 views
1

使用MEF我想要執行以下操作。MEF,在請求分支時創建導入樹

我有一個WPF Shell。我想從另一個DLL中導入一個UserControl,它也是我的MVP三元組視圖。 MVP三元組的工作方式是,在演示者中,我有一個構造函數,它同時使用IModel和IView並將它們連接起來。 因此,爲了使這項工作,我需要MEF做到以下幾點:

  1. 創建的iView實現
  2. 創建IModel實施
  3. 創建演示,並通過IModel和IVIEW其構造
  4. 進口當它顯示時,將Iiew實現到我的外殼中

取而代之的是,它只創建類型Exporting IView並將其傳遞到shell,基本上是skipp第2步和第3步。當你考慮這個問題時,它非常合乎邏輯,但是我怎麼能告訴MEF在我請求一個IView時也創建整個黑社會。 我不需要引用Presenter,也不需要在我的Shell .dll中的任何其他位置引用模型,因此將它作爲Import也不是一個選項(並且無論如何它都會非常難看:)。

我正在使用最新版本的MEF(預覽2刷新)。 有人嗎?

== ==更新

我找到了一個解決方案,我的博客上講述在這裏:
Krzysztof Koźmic's blog - Creating tree of dependencies with MEF

不過,我會很樂意,如果有人想出了一個更好的解決方案。**

+0

你把[ImportingConstructor]放在構造函數上了嗎? – 2008-11-07 00:15:41

+0

是的,我檢查了我提供的鏈接,有一個簡化版本的代碼和我的解決方案。它的工作原理,但我想知道是否有更好的方法來做到這一點。 – 2008-11-07 06:43:31

回答

2

請在這裏查看我的答案。

http://codebetter.com/blogs/glenn.block/archive/2008/11/12/mvp-with-mef.aspx

編輯:(從鏈接添加,以防止不被標記爲低質量/ LOA

1: using System.ComponentModel.Composition; 
    2: using System.Reflection; 
    3: using Microsoft.VisualStudio.TestTools.UnitTesting; 
    4: 
    5: namespace MVPwithMEF 
    6: { 
    7:  /// <summary> 
    8:  /// Summary description for MVPTriadFixture 
    9:  /// </summary> 
    10:  [TestClass] 
    11:  public class MVPTriadFixture 
    12:  { 
    13:   [TestMethod] 
    14:   public void MVPTriadShouldBeProperlyBuilt() 
    15:   { 
    16:    var catalog = new AttributedAssemblyPartCatalog(Assembly.GetExecutingAssembly()); 
    17:    var container = new CompositionContainer(catalog.CreateResolver()); 
    18:    var shell = container.GetExportedObject<Shell>(); 
    19:    Assert.IsNotNull(shell); 
    20:    Assert.IsNotNull(shell.Presenter); 
    21:    Assert.IsNotNull(shell.Presenter.View); 
    22:    Assert.IsNotNull(shell.Presenter.Model); 
    23:   } 
    24:  } 
    25: 
    26:  [Export] 
    27:  public class Shell 
    28:  { 
    29:   private IPresenter _presenter = null; 
    30:   
    31:   public IPresenter Presenter 
    32:   { 
    33:    get { return _presenter; } 
    34:   } 
    35: 
    36:   [ImportingConstructor] 
    37:   public Shell(IPresenter presenter) 
    38:   { 
    39:    _presenter = presenter; 
    40:   } 
    41:  } 
    42: 
    43:  public interface IModel 
    44:  { 
    45:  } 
    46: 
    47:  [Export(typeof(IModel))] 
    48:  public class Model : IModel 
    49:  { 
    50:   
    51:  } 
    52: 
    53:  public interface IView 
    54:  { 
    55:  } 
    56: 
    57:  [Export(typeof(IView))] 
    58:  public class View : IView 
    59:  { 
    60:  } 
    61: 
    62:  public interface IPresenter 
    63:  { 
    64:   IView View { get;} 
    65:   IModel Model { get; } 
    66:  } 
    67: 
    68:  [Export(typeof(IPresenter))] 
    69:  public class Presenter : IPresenter 
    70:  { 
    71: 
    72:   private IView _view; 
    73:   private IModel _model; 
    74: 
    75:   [ImportingConstructor] 
    76:   public Presenter(IView view, IModel model) 
    77:   { 
    78:    _view = view; 
    79:    _model = model; 
    80:   } 
    81: 
    82:   public IView View 
    83:   { 
    84:    get { return _view; } 
    85:   } 
    86: 
    87:   public IModel Model 
    88:   { 
    89:    get { return _model; } 
    90:   } 
    91: 
    92:  } 
    93: } 

所以這是怎麼回事呢?

殼牌獲得Presenter注入。 Presenter獲取視圖和模型注入。這裏的一切都是單身,但不一定是。

我們兩個例子的區別在於Presenter被注入到shell而不是View中。如果演示者正在創建視圖,那麼您不能只抓住視圖(就像他在做的那樣),否則演示者不會被創建。那麼你可以做到這一點,但你最終將它砍成碎片。清潔工只需要注入Presenter並讓它暴露出一個IView。我們在Prism中做到了這一點,它工作得很好。

1

您在博客文章中列出的方式是利用MEF的完美方法。這是嵌套組合,設計時始終注意Container是決定因素,因此作爲插件/擴展器供應商,您將專注於您正在「導出」的服務,作爲一項重要的應用,您不應該不用擔心你需要提供服務,或者「進口」(這一點在最後一滴中有一些問題,但是我聽到了足夠的樂觀看法)。

因此,在嵌套組合中,您可能需要一些外部服務,但當時您也可以提供一些服務。當你撰寫文章時,它會將所有內容連接在一起。

我有一個包含2個例子說明這種思維方式博客文章:

http://www.sidarok.com/web/blog/content/2008/09/26/what-is-this-managed-extensibility-framework-thing-all-about.html

此外,要刪除DLL和觀看它的類型,可以使用DirectoryPartCatalog觀看該文件夾。

您還需要注意同一合同有多個導出的情況,並根據所提供的元數據確定正確的導出。