Visual Studio 2010 MEF vs MPF?

7
我正在考虑将一种新的编程语言添加到Visual Studio 2010中,但对于最佳方法感到有些困惑。
我已经研究了MPF,并找到了一些如何进行语法高亮、链接外部解析器等的示例,似乎非常简单明了。
然后我读到了关于MEF的一些内容,以及它是Visual Studio的新可扩展模型。我尝试使用一些样例并成功实现了语法高亮。现在,我不知道该如何像MPF一样使用ParseSource等方式来链接我的语言解析器。顺便说一下,我正在使用ANTLR。
MEF只用于编辑器的视觉方面,例如高亮、装饰等吗?还是可以/建议使用它来实现语言服务?
据我所知,MEF是新的、推荐的方法,但相比常规的MPF似乎更难创建一个新的语言。MPF仍然是一个好的方法吗?

3
其中最好的方法之一是通过研究当前项目的做法。尝试查看IronPython和“Python Tools for Visual Studio”,以了解它们如何为VS添加对Python语言的支持。 - Alan Barber
这个问题仍然没有被接受的答案。我的回答有帮助到你吗?还是你需要更多的细节?=3 - Ray
哎呀,我都忘了这件事了,那是一段时间以前的事情了。你的回答非常有帮助,谢谢你,我选择了 MPF 路线。 - David James Ball
3个回答

5
MEF(托管可扩展性框架)是.NET中一种通用的编程方法,用于扩展程序,如Visual Studio。VS包/扩展可以使用较新的VS-MEF类(合同),而不是MPF类。 MEF由装饰有[Export]属性的类识别。通常来说,您继承一个特定的类,比如可着色项,并将其导出到Visual Studio中,然后Visual Studio查找MEF包中的所有导出并导入它们。
MPF(托管包框架)就像是围绕非托管/本机VS扩展模型的旧COM包装器的类系统。通过获取服务并实现MPF类的方法来以编程方式扩展Visual Studio(MPF类反过来实现了COM包装器的COM样式接口。例如LanguageService实现IVsLanguageInfo和其他接口,但它只是简单地“收集”这些接口的方法,然后您可以在实现LanguageService的类中覆盖它们)。
如果您想实现完整的编程语言,则需要结合使用MPF和MEF。您可以在编辑器部分(如标记化(这对于语法突出显示是必需的),概述,括号匹配等)中使用MEF,而在其他VS内容(如新工具窗口,属性页面等)中使用MPF。

除了MPF,您还可以使用旧的COM包装器,但是MPF类已经为您完成了一些COM工作,如果选择COM包装器,则必须处理这些工作。

您也可以使用MPF实现标记器等,但我尝试过,发现它比MEF更加不直观。如果问我,它比MEF更难,并且需要更多的脑力劳动,但我用MPF取得的进展远远超过了MEF。

这对我来说有点混乱,因为我注意到MSDN混淆了MEF和MPF的文章。您需要非常仔细地观察MSDN的哪个子部分,您可能会意外地从MEF类别切换到MPF。 但是,MSDN在一些关于扩展VS的常规文章中提示您什么是什么,例如在此处:http://msdn.microsoft.com/en-us/library/cc138569.aspx


n.b. 关于“…MPF 类实现 COM-like 接口 [用于] LanguageService [它实现了] IVsLanguageInfo…” 最近在 vs2017 15.8 中,你提到的特定用途已经通过 MEF 得到了启用。所以我很傻,就在我认为他们已经放弃将 完整的 遗留 VSIX 生态系统转换为 MEF(尽管对于一个外行人来说,这似乎是一项“半途而废”的努力)时,他们显然还在继续努力。非常好的答案。 - Glenn Slayden

1

我目前正在使用MEF(在VS2013中)独家实现语言服务。

除了语法高亮(可以使用ITagger<ClassificationTag>完成)和其他一些内置的特定用途的MEF接口(例如选项页面和各种类型的智能感知),需要按需实现,为了执行后台解析等操作,通常要实现IVsTextViewCreationListener并在打开文件时执行相关操作;或者,您可以使用包的Initialize方法作为入口点,在后台遍历项目层次结构。

智能感知功能等通常需要您响应某个命令(或监视按键以了解何时弹出完成列表框,例如);您可以通过实现IOleCommandTarget并处理相关命令来处理此操作(当创建文本视图时,通过在IVsTextView上调用AddCommandFilter手动钩取命令处理程序)。

到目前为止,我没有遇到任何无法通过MEF完成的任务(除了根本无法完成的任务);我从未真正研究过MPF,因为我不需要它。

(请注意,最终代码往往类似于MEF管道、VS SDK接口和辅助类以及EnvDTE混乱的汤。)

1
对于那些不是明确由MEF支持的高级场景,这里有一个技巧:一旦将ITextView转换为IWpfTextView,就会在其Properties属性中匿名存储大量的遗留shim,类似于WPF风格的“附加属性”用法(即未经过类型化的键值对)。其中大多数都无法通过MEF声明性归因模型获得。您可以通过替换自己的处理程序来挂钩您感兴趣的shim,然后在适当时候推迟到(保留的)前者。 - Glenn Slayden
@GlennSlayden 不错的建议。我们还没有需要包装它们中的任何一个,但从属性中获取 ITextDocument 已经被证明很有用了。 - Cameron

1
使用MEF来处理通过MEF公开的功能。其他功能将根据具体情况进行处理(如果您在实现特定功能时遇到问题,请提出具体问题)。我仍然使用MPF来处理项目系统(项目的MPF,或MPFProj)。为了处理后台解析,我建议查看我的BackgroundParser实现(MIT许可证)。它运行得非常好,尽管回头看,我希望我使用TPL并使ReParseImpl返回一个Task而不是同步执行。

提醒您关注我的评论,因为我先没有看到您的评论,后来才意识到您可能会感兴趣。 - Glenn Slayden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接