使用MEF我想做以下事情。
我有一个WPF Shell。对于shell我想从另一个DLL导入一个UserControl,它也是我的MVP三元组的视图。 MVP三元组的工作方式是,在演示者中我有一个构造函数,它接受IModel和IView并将它们连接起来。 因此,为了实现这一点,我需要MEF来执行以下操作:
相反它的作用是,它只创建Exporting IView类型并将其传递给shell,基本上跳过了第2步和第3步。当你想到它时,它非常合乎逻辑,但我怎么能告诉MEF也创建了当我要求IView时整个三合会。 我不需要在我的Shell中引用Presenter或模型。所以将它作为Import也不是一个选项(无论如何它都会非常丑陋:)。
我正在使用最新的MEF(预览2刷新)。 任何人吗?
==更新==
我找到了一个解决方案,我在这里写了一篇博文:
Krzysztof Koźmic's blog - Creating tree of dependencies with MEF
但是,如果有人想出更好的解决方案,我会非常高兴。**
答案 0 :(得分: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: }
那么这里发生了什么?
Shell会注入Presenter。 Presenter注入了View和Model。这里的一切都是单身人士,但并非必须如此。
我们的两个例子之间的区别在于Presenter被注入shell而不是View。如果Presenter正在创建View,那么您不能只是首先抓取View(就像他正在做的那样),否则将无法创建Presenter。嗯,你可以做到,但你最终会破解它。 Cleaner只是注入Presenter并让它暴露出IView。我们在Prism中做到了这一点并且效果很好。
答案 1 :(得分:1)
您在博文中概述的方式是使用MEF的完美有效方式。这是嵌套的组合,在设计时总是要记住Container是决策者,所以作为插件/扩展器供应商,你将专注于你“出口”的服务,作为一个重要的,你不应该不用担心你需要服务什么,或者“导入”(这一点在最后一滴中有一些问题,但我听到足够好以对它持乐观态度)。
因此,在嵌套组合中,您可能需要一些外部服务,但当时您也可以提供一些服务。当你做作曲时,它会将所有东西都插在一起。
我有一篇博客文章,其中包含两个说明这种思维方式的例子:
此外,要删除dll并观察其中的类型,您可以使用DirectoryPartCatalog来查看该文件夹。
您还需要注意同一合同有多个导出的方案,并根据提供的元数据确定正确的方案。