如何使共用MonoDevelop.Xml类库的两个VS扩展独立正常工作?
解决方法
1. 不要直接打包第三方MEF组件
别在你的VSIX清单里直接添加MonoDevelop.Xml的MEF组件资产,只导出你自己实现的IAsyncCompletionSourceProvider。同时给你的导出类加上专属标识和优先级,避免和MonoDevelop.MSBuildEditor的组件冲突:
[Export(typeof(IAsyncCompletionSourceProvider))] [Name("RimWorldXmlCompletionProvider")] [Order(Before = "DefaultXmlCompletionProvider")] public class RimWorldXmlCompletionSourceProvider : IAsyncCompletionSourceProvider { // 你的自定义补全逻辑实现 }
2. 配置软依赖+私有资产
- 打开VSIX清单的「依赖项」标签页,添加MonoDevelop.Xml的组件ID,将依赖类型设置为可选。这样你的扩展不会强制要求对方安装,但如果系统里有该组件就优先复用。
- 把MonoDevelop.Xml的相关DLL设为你的扩展私有资产:在项目中引用这些DLL,设置「复制到输出目录」为「始终复制」;然后在VSIX清单的「资产」标签页,添加这些DLL作为
Microsoft.VisualStudio.Assembly类型,勾选「私有」选项。
这套配置的作用是:当MonoDevelop.MSBuildEditor安装时,VS会优先使用它加载的MonoDevelop.Xml组件,避免冲突;当对方未安装时,你的扩展会调用自己的私有副本,保证独立运行。
3. 动态检测组件状态
在扩展初始化代码里,检查MonoDevelop.Xml的核心MEF组件是否存在,不存在就手动加载私有副本的组件:
protected override void Initialize() { var componentModel = (IComponentModel)GetService(typeof(SComponentModel)); var xmlProviders = componentModel.GetExtensions<IAsyncCompletionSourceProvider>(); bool hasXmlCore = xmlProviders.Any(p => p.GetType().Namespace.StartsWith("MonoDevelop.Xml")); if (!hasXmlCore) { // 手动组合私有副本的MEF核心组件 var container = new CompositionContainer(); container.ComposeParts(this, new XmlCompletionProvider()); // 替换为实际的核心组件类 } }
4. 验证两种场景
- 单独安装你的扩展,测试补全功能是否正常;
- 安装MonoDevelop.MSBuildEditor,确认两个扩展可以同时工作;
- 禁用MonoDevelop.MSBuildEditor,检查你的扩展是否仍能独立运行。
内容的提问来源于stack exchange,提问作者Dark Daskin
相关产品推荐
相关产品推荐

