2008-11-05 54 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观看该文件夹。

您还需要注意同一合同有多个导出的情况,并根据所提供的元数据确定正确的导出。