Packages |
The Base Extensions Library for Visual Studio consists of a number separate service and utility libraries designed to simplify Visual Studio extension development. The Managed Extensibility Framework (MEF) places a number of restrictions on the manner in which reusable software components may be developed and shared between multiple extensions, so the library is separated according to the type of feature provided by each package.
MEF Service libraries include one or more new services which are provided through an [Export] attribute. Each of these libraries consists of two separate assemblies: an implementation assembly which provides the service and an interfaces assembly which defines interfaces through which other extensions can use and/or extend the behavior of the service.
Currently the following MEF Service libraries are included.
While Visual Studio's VSIX Installer automatically installs nested VSIX references (which is the method by which the MEF services extensions are delivered), the Visual Studio SDK will not perform this installation automatically in the experimental instance. After launching the experimental instance for the first time (or after you reset it), you will need to install the VSBase Services Debugging Support extension from the Visual Studio Gallery and restart the experimental instance before your extension will work.
Note |
---|
Future releases of individual extensions may improve support in this area by updating the .targets file included in the implementation to automatically deploy the nested VSIX extension(s) to the experimental instance for debugging purposes. Stay tuned! |
Utility libraries do not export any MEF components. As such, these libraries are safe for use in side-by-side loading scenarios. A copy of the assembly should be included in the distribution of your Visual Studio extension. When a utility library package is installed through NuGet, the assembly will be included in the resulting VSIX file by default.
Currently the following Utility libraries are included.
Special steps are required to ensure that Visual Studio will be able to locate utility library assemblies at runtime. The specific configuration steps to take depend on the minimum version of Visual Studio your extension will support.
Note |
---|
These configuration steps should be performed in the project that creates your VSIX extension, even if another assembly actually references the utility library. |
Regardless of the version of Visual Studio you are supporting, you need to make sure your extension is configured to generate a pkgdef file. Open your extension's project file in an XML editor and ensure that the following two properties are set to true.
<GeneratePkgDefFile>true</GeneratePkgDefFile> <CopyBuildOutputToOutputDirectory>true</CopyBuildOutputToOutputDirectory>
The second step to configuring the extension is updating your source.extension.vsixmanifest file to include a line to inform Visual Studio that your extension includes a pkgdef file. If you are using version 1 of this file (i.e. the file starts with <Vsix Version="1.0.0"), make sure the following line is included inside the <Content> element.
<VsPackage>|%CurrentProject%|</VsPackage>
If your extension uses version 2 of this file, [TODO: fill this in].
If your extension only supports Visual Studio 2012 and newer, the ProvideCodeBaseAttribute provides the most efficient method for registering utility libraries with Visual Studio. To use this attribute, simply add a reference to the VSSDK.Shell.11 (for extensions targeting Visual Studio 2012 and newer) or VSSDK.Shell.12 (for extensions targeting Visual Studio 2013 and newer) NuGet package. Specific values for the AssemblyName, AssemblyVersion, and AssemblyFile placeholders are described in the documentation for the specific utility library.
[assembly: ProvideCodeBase( AssemblyName = "{AssemblyName}", Version = "{AssemblyVersion}", CodeBase = "$PackageFolder$\\{AssemblyFile}")]
If your extension supports Visual Studio 2010, you will need to include a copy of the following registration attribute in your extension code.
using System; using System.Reflection; using System.Runtime.InteropServices; using Microsoft.VisualStudio.Shell; [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] internal sealed class ProvideBindingPathAttribute : RegistrationAttribute { private static string GetPathToKey(RegistrationContext context) { Guid componentGuid = GetAssemblyGuid(context.CodeBase); return string.Concat(@"BindingPaths\", componentGuid.ToString("B").ToUpperInvariant()); } private static Guid GetAssemblyGuid(string codeBase) { string assemblyFile = new Uri(codeBase).LocalPath; Assembly assembly = Assembly.LoadFrom(codeBase); object[] attributesData = assembly.GetCustomAttributes(typeof(GuidAttribute), false); if (attributesData.Length == 0) throw new ArgumentException("The specified assembly did not contain a [Guid] attribute."); return new Guid(((GuidAttribute)attributesData[0]).Value); } public override void Register(RegistrationContext context) { if (context == null) throw new ArgumentNullException("context"); using (Key childKey = context.CreateKey(GetPathToKey(context))) { childKey.SetValue(context.ComponentPath, string.Empty); } } public override void Unregister(RegistrationContext context) { if (context == null) throw new ArgumentNullException("context"); context.RemoveKey(GetPathToKey(context)); } }
To use the attribute make sure your AssemblyInfo.cs contains the following line.
[assembly: ProvideBindingPath]