【发布时间】:2010-04-16 18:11:03
【问题描述】:
更新
当我试图让 MEF 在我的整个应用程序中工作时,我遇到了更多的地方,我只是不明白为什么它没有在我期望的时候自动创建我的库。我认为这一切都回到了 Reed 所说的需要 MEF 来创造一切。所以现在,我有一个需要使用我的 CandySettings 的 XML 阅读器类,但即使它的 ICandySettings 属性具有 [Import] 属性,它也不会被导入。首先我发现 [Import] 不适用于静态,所以我改变了这个。但在那之后它仍然没有工作。我认为这是因为我手动创建了 XML 阅读器对象,而 MEF 想要我做的是 [Import] XML 阅读器......这意味着我现在也必须有一个接口。
这几乎就像使用 IoC(或至少对于 MEF)一样,是全有或全无的事情。你不能随意地到处使用它,因为最终你想要注入属性的任何类也需要由 MEF 创建。
如有错误请指正!
原帖
嗯,还没有那么糟糕。 :) 但是在 Reed 向我指出 MEF 作为 IoC 的潜在替代品之后,我确实有疑问(到目前为止它看起来确实不错)。
考虑以下模型: alt text http://bit.ly/9W0sHt
如您所见,我有一个应用程序,该应用程序使用插件(哎呀,错过了那个关联!)。应用程序和插件都需要使用 CandySettings 类型的对象,该对象可在另一个程序集中找到。
我第一次尝试在 MEF 中使用 ComposeParts 方法,但我可以让它工作的唯一方法是在 plugin 代码中执行类似的操作。
var container = new CompositionContainer();
container.ComposeParts(this, new CandySettings());
但这没有任何意义,因为我为什么要在插件中创建 CandySettings 的实例?它应该在应用程序中。但是如果我把它放在 App 代码中,那么即使我在插件中使用 [Import],在 CandySettings 中使用 [Export],插件也不会神奇地弄清楚如何访问 ICandySettings。 EDIT(可能是因为我应该从 App 调用 ComposeParts() 然后将其传递给插件?)
我这样做的方法是使用 MEF 的 DirectoryCatalog,因为这允许插件在构建时扫描当前文件夹中的所有程序集并自动导入所有标有 [导入]属性。所以它看起来像这样,并且可能在 every 插件中:
var catalog = new DirectoryCatalog(".");
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
这完全有效,但我不禁认为这不是 MEF 的预期用途?
【问题讨论】:
-
我记得使用 MEF 存在一些实际限制,并且它的预期用途是用于 Visual Studio 等应用程序,因此您应该首先确保您的设计符合他们的假设。基本上说这“不适合所有人”。 codebetter.com/blogs/glenn.block/archive/2009/08/16/…
-
我认为它会成功,但这是我现在成为 .NET 程序员所期望的事情之一。给猫剥皮的方法有很多,基本上你能弄明白的唯一方法就是尝试几种方法。到目前为止,我已经在 MEF 和 Unity 中实现了我的代码,并且两者都可以工作,尽管我仍然不确定我在这两个框架中的实现方式是否 100% 正确。
-
您能否添加您从
ComposeParts获得的错误消息、您用于初始化容器的代码以及您用于导出/导入的代码? -
@Daniel:好的,我再次修改了我的问题。感谢您的关注!
-
听起来您有两种标记为
[Export(typeof(IError))]。如果是这样,则组合不知道在构建插件时使用哪一个。您应该开始针对新问题提出新问题,以便正确关联答案。这个太长了,对新人有用。
标签: c# dependency-injection inversion-of-control ioc-container mef