You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将DevForce Punch集成到Visual Studio 2017内部Composition Container?

我来帮你搞定VSIX和Cocktail容器集成的问题!你的核心痛点是VS用自己独立的MEF容器,导致Cocktail的容器和VS的容器无法互通,进而MEF导出不被识别。下面是具体的实现步骤和代码示例:

解决步骤

1. 获取VS内部的MEF组合容器

你已经拿到了DTE和ServiceProvider的引用,接下来要通过它们获取VS的核心MEF容器:

// 从ServiceProvider获取VS的ComponentModel服务
var componentModel = (IComponentModel)sp.GetService(typeof(SComponentModel));
// 拿到VS默认的组合容器
var vsCompositionContainer = componentModel.DefaultCompositionContainer;

这里的SComponentModel是VS暴露自身MEF容器的关键服务,通过它就能拿到VS内部管理所有扩展性部件的容器实例。

2. 将VS容器集成到Cocktail的容器体系

Cocktail的CompositionHost支持两种方式集成外部容器,根据你的需求选一种即可:

方式一:把VS容器作为外部依赖容器

这种方式下Cocktail会保留自己的容器,但会优先从VS容器中解析服务,适合需要同时管理自有部件和VS服务的场景:

// 创建Cocktail容器配置
var config = new CompositionHostConfiguration();
// 添加VS容器作为外部容器
config.AddExternalContainer(vsCompositionContainer);
// 初始化Cocktail宿主
var cocktailHost = CompositionHost.Initialize(config);

方式二:直接复用VS容器作为Cocktail的宿主

这种方式更适合VSIX场景,因为所有部件都直接在VS的容器中管理,能确保你的MEF导出被VS正确识别:

// 直接用VS的容器初始化Cocktail宿主
var cocktailHost = new CompositionHost(vsCompositionContainer);

3. 注册你的自定义MEF部件

不管用哪种方式,最后都要把你VSIX里的MEF导出部件注册到容器中:

// 组合当前类中的MEF导出(如果你的Package类有导出的话)
cocktailHost.ComposeParts(this);

// 如果有其他独立的MEF部件,也可以这样注册
// cocktailHost.ComposeParts(new MyCustomExportedService());
完整的Package类示例

把这些逻辑放到VSIX的Package类的Initialize方法里(这是VS服务初始化完成后的安全时机):

using System;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.ComponentModelHost;
using DevExpress.Cocktail;
using EnvDTE80;
using Microsoft.VisualStudio.OLE.Interop;

namespace YourVsixProject
{
    [PackageRegistration(UseManagedResourcesOnly = true)]
    [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
    [Guid(PackageGuidString)]
    public sealed class YourVsixPackage : Package
    {
        public const string PackageGuidString = "your-guid-here";

        protected override void Initialize()
        {
            base.Initialize();

            // 获取VS的DTE和ServiceProvider
            var dte2 = (DTE2)Package.GetGlobalService(typeof(SDTE));
            var sp = new ServiceProvider(dte2 as IServiceProvider);

            // 获取VS的MEF容器
            var componentModel = (IComponentModel)sp.GetService(typeof(SComponentModel));
            var vsCompositionContainer = componentModel.DefaultCompositionContainer;

            // 集成到Cocktail(这里用方式二,直接复用VS容器)
            var cocktailHost = new CompositionHost(vsCompositionContainer);
            // 注册自定义部件
            cocktailHost.ComposeParts(this);
        }
    }
}
注意事项
  • 确保项目引用了Microsoft.VisualStudio.ComponentModelHost程序集(用来获取IComponentModel)。
  • 你的MEF导出类要正确标记[Export]属性,比如导出接口要写[Export(typeof(IMyService))]。
  • 如果需要VS主动识别你的导出,还可以配合VS的[ProvideExportedService]等属性一起使用。

内容的提问来源于stack exchange,提问作者MrTouya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:29:19