![]() |
1
7
我正在MEF上构建一个完全成熟的可扩展应用程序(并将WPF与MVVM模式一起使用)。我将构建和开放源代码IT的基本应用程序框架作为 SoapBox Core . 我还在代码项目上发布了一个基于Soapbox核心的演示: Building an Extensible Application with MEF, WPF, and MVVM . 我不确定使用MVVM是否适用于您,但如果适用,那么通过查看使用MEF实现MVVM,您可能会学到很多东西。尤其是它导入视图的方式。 就最佳实践而言…我创建了一个扩展的嵌套层次结构(所以基本模块称为主机,它所做的只是组成应用程序并导入一些基本扩展)。然后,这些扩展公开了其他扩展点,并且应用程序在运行它时会自行构建(组合和扩展之间的交叉)。 为了保持所有的内容都是正确的,我将扩展层次结构放入一组静态类中。例如,核心框架提供的所有扩展点如下:
因此,如果希望扩展名向“文件”菜单中添加某些内容,则可以导出实现合同名为soapbox.core.extensionpoints.workbench.mainmenu.file menu的IMenuItem的内容。 每个扩展都有一个“id”,它只是一个字符串标识符。这些现有ID在另一个层次结构中定义:
正如你所看到的,filemenu已经包含了一个出口扩展(这是为关闭应用程序而预先编程的)。如果要向“文件”菜单添加扩展名,您可能希望它出现在“退出”菜单项之前。IMenuItem继承自IExtension,它有两个属性:
因此,您的扩展将为insertrelativeID返回soapbox.core.extensions.workbench.mainmenu.filemenu.exit,并为beforeafter属性(枚举)返回beforeafter。当工作台导入所有文件菜单扩展名时,它将根据这些ID对所有内容进行排序。这样,以后的扩展就相对于现有的扩展插入自己。 |
![]() |
2
6
最佳实践是使用共享(单例)模型。这就给我们带来了设计考虑,建议您将可导出部分设计为无状态和线程安全的,这样它们就不会受到同一实例上的多个调用(可能在不同线程上)的影响。 如果单例模型不适合您,建议使用构建器模式(将导出的部分与实际的实例化分开)。 您应该记住,使用非共享模型是非常昂贵的,因为它使用反射来进行实际的实例化(通过使用构建器模式,您可以以更少的代价获得相同的结果)。 也看这里 http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/01/09/mef-for-beginner-toc.aspx 当然,你知道你可以在这里找到信息: http://mef.codeplex.com |
![]() |
3
2
我对MEF还是很陌生,但我想在这场讨论中添加更多内容,因为当我试图弄明白为什么事情不能按我期望的方式工作时,我会不断经历地狱。
首先,在使用MEF时,我建议将System.ComponentModel.Composition添加到解决方案中,而不仅仅是添加对程序集的引用。尽管在MEF中调试问题感觉像是一场递归的噩梦,但当您无法找出问题所在时,这是绝对不可避免和至关重要的。
这就引出了我的下一点,那就是永远不要忘记,MEF不知道你不告诉它什么,或者,如果你不正确地告诉它, 。例如,我的alpha应用程序与mef一起工作得很好——我让它在主GUI中组成部分,容器加载的所有程序集(它们是主应用程序的依赖项)都导出了必要的接口。事情进展顺利,我能够让MEF在我想要的时间和地点解决实例。
但是,我刚开始研究下一个版本;一些插件被加载(那些导出了接口,但没有导入要求的插件),而其他插件则没有(那些确实需要导入的插件)。这一次,我在负责加载插件的ApplianceManager类中编写了一些部分,但是插件需要解析来自应用程序中其他类(在我的例子中是模型)的导入。我认为这应该是自动发生的,特别是在目录结构中可以看到那些程序集被检测到…但我还是不能让它工作…这让我回到了我的第一点——添加源代码,而不仅仅是程序集。调试这个几乎让我发疯,但我最终会在努力地逐步通过MEF代码之后发现它。: 我想看到有人对这个问题给出了一个答案,这个问题讨论了易于MEF集成的体系结构。关于工具栏菜单之类的问题的答案确实很好,但是我想看到一些关于完全驻留在MVVM模型侧的东西的讨论。比如插件管理器、数据库、插件和共享库的排列方式。我仍在试图弄明白为什么我有一个相当好的时间让我的第一个mef应用程序工作,但在获得更多的“经验”后,我不能让我的新应用程序100%工作。 更新2010-06-09 我想增加另一个可能的做法,以帮助您导航通过mef灌木。今天,我需要对那个项目做一个我“只是不知道”的健全检查,所以我创建了一个简单的、非常规的UML类图,在这个类图中,我使用依赖项来标记导入和导出。以下是我发现的,这使问题非常清楚。
工作应用:
非工作应用:
那不是很愚蠢吗?模型没有装载,它自己就在一个岛上。我相信这就是为什么我基于MEF的依赖关系没有得到解决的原因(如果有人可以纠正我,如果我在这里是错的,我会感激,尽管!) 当我试图弄明白为什么事情不能像我期望的那样运作的时候,我常常会下地狱。
首先,在使用MEF时,我建议将System.ComponentModel.Composition添加到解决方案中,而不仅仅是添加对程序集的引用。尽管在MEF中调试问题感觉像是一场递归的噩梦,但当您无法弄清楚到底出了什么问题时,这是绝对不可避免的,也是至关重要的。 这让我进入下一个观点,那就是永远不要忘记,我不知道你不告诉我什么,或者 如果你说得不恰当 . 例如,我的alpha应用程序与mef一起工作得很好——我让它在主GUI中组成部分,容器加载的所有程序集(它们是主应用程序的依赖项)都导出了必要的接口。事情进展顺利,我能让MEF在我想要的时间和地点解决问题。 但是,我刚开始研究下一个版本;一些插件被加载(那些导出了接口,但没有导入要求的插件),而其他插件则没有(那些确实需要导入的插件)。这一次,我在负责加载插件的ApplianceManager类中编写了一些部分,但是插件需要解析来自应用程序中其他类(在我的例子中是模型)的导入。我认为这应该是自动发生的,特别是在目录结构中可以看到那些程序集被检测到…但我还是不能让它工作…这让我回到了我的第一点——添加源代码,而不仅仅是程序集。调试这个几乎让我发疯,但我最终会在努力地逐步通过MEF代码之后发现它。:) 我想看到有人对这个问题给出了一个答案,这个问题讨论了易于MEF集成的体系结构。关于工具栏菜单之类的问题的答案确实很好,但是我想看到一些关于完全驻留在MVVM模型侧的东西的讨论。比如插件管理器、数据库、插件和共享库的排列方式。我仍在试图弄明白为什么我有一个相当好的时间让我的第一个mef应用程序工作,但在获得更多的“经验”后,我不能让我的新应用程序100%工作。 更新2010-06-09 我想增加另一个可能的做法,以帮助您导航通过mef灌木。今天,我需要对那个项目做一个我“只是不知道”的健全检查,所以我创建了一个简单的、非常规的UML类图,在这个类图中,我使用依赖项来标记导入和导出。这是我发现的,这使问题非常清楚。
工作应用:
非工作应用:
那不是很愚蠢吗?模型没有装载,它自己就在一个岛上。我 相信 这就是我基于MEF的依赖关系没有得到解决的原因(如果有人能纠正我,如果我在这里是错的,我会很感激!) |
![]() |
Bigeyes · 如何在MVVM模式中添加行? 8 年前 |
![]() |
User9898 · 悬停回到原始颜色时为什么选择 9 年前 |
![]() |
Huma Ali · WCF已完成事件中的异常处理 9 年前 |
![]() |
Nerd in Training · 文件副本发布错误 10 年前 |