如何获取VSPackage MSVS扩展中的Package对象的引用?

时间:2014-03-22 19:54:36

标签: c# visual-studio vspackage

我在C#中创建了我的第一个Visual Studio扩展(VSPackage)。我有两个课程:

class MyPackage : Package
{
    ...
}

class SomeOtherClass
{
    ...
}

在加载包之后实例化SomeOtherClass的对象,并且需要获取对MyPackage实例的引用。有没有办法获得对MyPackage对象的引用,而不是将其作为SomeOtherClass的构造函数中的参数传递?

3 个答案:

答案 0 :(得分:1)

如果我理解你的问题是对的,你可以这样做:

class MyPackage : Package
{
    private static MyPackage _instance;
    public static MyPackage Instance
    { 
        get
        {
            if(_instance != null)
                _instance = new MyPackage();
             return _instance;
         }
     }
}

class SomeOtherClass
{
     void Whatever()
     {
           // use MyPackage.Instance
     }
}

但只有在整个应用程序的整个生命周期中都需要一个MyPackage实例时,这才是可靠的。否则,将MyPackage的新实例传递给SomeOtherClass。

编辑:局部变量_instance也应该是静态的;我错过了。

答案 1 :(得分:1)

您可以使用IVsShell.IsPackageLoaded方法获取对任何已加载的VsPackage的引用。

使用IVsShell基础设施SVsServiceProvider属性导入的Import可以获得对MEF的引用。

同样,您可以使用ServiceProvider.GlobalProvider来获取对IVsShell的引用。

答案 2 :(得分:1)

我对SergeyT的答案投了赞成票。原因是这样的:

VS Package不仅仅是可以像其他任何类一样实例化的类。这是一个特殊的类,由Visual Studio加载,并作为Singleton保留在内存中。该程序包被连接到各种VS事件中,并旨在为整个扩展的各个部分提供功能。

获取它的实例与获取Visual Studio加载的实际包不同。

要完成您要执行的操作,您需要使用SergeyT建议的代码:

 var vsShell = (IVsShell) ServiceProvider.GlobalProvider.GetService(typeof(IVsShell));
        if(vsShell.IsPackageLoaded(MyPackageGuid, out var myPackage) 
           == Microsoft.VisualStudio.VSConstants.S_OK) { 
        _myPackage = (IMyPackage)myPackage;
        }

这样做,可以确保获得唯一的Package引用,而不仅仅是类的实例。