As we’ve seen, the VSIX extension project is composed of a few different files, all paved down by adding an extensibility project item. The core package class file contains the logic for our package.
Because packages are dynamic link libraries (DLLs), VSIX projects are class library projects. The core code file that is created implements a class called Microsoft.VisualStudio.Shell.Package
. This class contains all the necessary interfaces to make the package work within the context of the IDE.
Referring back to our "Hello, World"
example of a custom command, Listing 15.1 shows the core Package
class as it was generated by the custom command project item template.
using System;
using System.Diagnostics;
using System.Globalization;
namespace HelloWorldExtension
{
/// <summary>
/// This is the class that implements the package exposed
/// by this assembly.
/// </summary>
/// <remarks>
/// <para>
/// The minimum requirement for a class to be considered a
/// valid package for Visual Studio is to implement the
/// IVsPackage interface and register itself with the shell.
/// This package uses the helper classes defined inside the
/// Managed Package Framework (MPF) to do it: it derives from
/// the Package class that provides the implementation of the
/// IVsPackage interface and uses the registration attributes
/// defined in the framework to register itself and its
/// components with the shell. These attributes tell the
/// pkgdef creation utility what data to put into the .pkgdef file.
/// </para>
/// <para>
/// To get loaded into VS, the package must be referred by
/// <Asset Type="Microsoft.VisualStudio.VsPackage" ...>
/// in .vsixmanifest file.
/// </para>
/// </remarks>
[PackageRegistration(UseManagedResourcesOnly = true)]
// Info on this package for Help/About
[InstalledProductRegistration("#110", "#112", "1.0",
IconResourceID = 400)]
[ProvideMenuResource("Menus.ctmenu", 1)]
[Guid(MyCommand1PackageGuids.PackageGuidString)]
[SuppressMessage("StyleCop.CSharp.DocumentationRules",
"SA1650:ElementDocumentationMustBeSpelledCorrectly",
Justification = "pkgdef, VS and vsixmanifest are valid VS terms")]
public sealed class MyCommand1Package : Package
{
/// <summary>
/// Initializes a new instance of the <see cref="MyCommand1"/> class.
/// </summary>
public MyCommand1Package()
{
//Inside this method you can place any initialization
//code that does not require any Visual Studio service
//because at this point the package object is created but
//not sited yet inside Visual Studio environment.
//The place to do all the other initialization is the
//Initialize method.
}
#region Package Members
/// <summary>
/// Initialization of the package; this method is called right
/// after the package is sited, so this is the place
/// where you can put all the initialization code that relies
/// on services provided by Visual Studio.
/// </summary>
protected override void Initialize()
{
MyCommand1.Initialize(this);
base.Initialize();
}
#endregion
}
}
The first thing to notice is that your package class (which will, by default, be named after the project item that you added) inherits from the Package
class:
public sealed class MyCommand1Package : Package
The Package
class, in turn, implements the IVsPackage
interface that provides the functionality necessary to expose the package and its functionality within the IDE.
This interface provides the eventing glue for packages. It is responsible for all the events that constitute the life span of an add-in.
Beyond the Package
class itself, there are other files created within the package project. There are resource files for defining string and bitmap resources and a .vsct
file and code files that define important commands for your package.