Mapping Host Types to Proxy Types

One of the required services that you must implement in the host application is a type map provider. Visual Studio Tools for Applications uses type maps to determine how to convert types between the object model of your host application and proxy types used by add-ins. A type map is a data structure that associates Type objects, which describe the types in the host application, with canonical names that uniquely identify each type. The type map provider is a class that associates the types in the host object model with canonical names.

You can use the Proxy Generation tool (ProxyGen.exe) to generate a type map provider. For more information about ProxyGen.exe, see Proxy Generation Tool (ProxyGen.exe).

After you generate the type map provider, you must expose it as a service to Visual Studio Tools for Applications. For more information, see Implementing Host Services.

Understanding Type Map Providers

A type map provider is a class in the host application that implements the ITypeMapProvider interface. This interface defines two methods that are called by Visual Studio Tools for Applications:

  • The GetTypeForCanonicalName method returns the host type that is associated with a specified canonical name. This method is called by Visual Studio Tools for Applications when the host application receives an object from the add-in, and the object is a proxy type (for example, as a parameter of a host method that was called by the add-in). The returned type information is used to help convert the proxy object to a host object.

  • The GetCanonicalNameForType method returns the canonical name that is associated with a specified host type. This method is called by Visual Studio Tools for Applications when the host application sends an object to the add-in, and the object is a host type (for example, as the return value of a host method that was called by the add-in). The returned canonical name is used to help convert the host object to a proxy object.

Understanding Canonical Names

A canonical name is a globally unique name that Visual Studio Tools for Applications uses to associate a proxy type used by add-ins with a type in the host application. A canonical name provides the uniqueness of a GUID, but it is easier to read. When you generate a type map provider, ProxyGen.exe creates canonical names in the format assembly name, fully qualified type name for managed types, and canonical names in the format type library name, fully qualified type name for COM types.

Note

Do not change the canonical name for a type after the type is published. If you change the canonical name for a type in a future version of your application, add-ins that are already using the type will be incompatible with the new version of your application.

Creating Type Map Providers

To create a type map provider, run ProxyGen.exe with the /c argument. ProxyGen.exe generates a C# code file that contains the definition of a class that implements the ITypeMapProvider interface.

The following example demonstrates how to run ProxyGen.exe at a command prompt to generate a type map provider. This command will generate a code file named Proxy.HostTypeMapProvider.cs that contains the type map provider implementation. For more information, see Proxy Generation Tool (ProxyGen.exe).

proxygen.exe /i:%SYSTEMDRIVE%\ShapeAppCSharp\Proxy\descriptor.xml /c:%SYSTEMDRIVE%\ShapeAppCSharp\Proxy\Proxy.cs

Design of the Generated Type Map Provider Class

The class generated by ProxyGen.exe has the following members.

AddCustomTypes Method

This method is useful if you prevent ProxyGen.exe from generating a proxy for a particular host type so that you can define the proxy yourself. Otherwise, you can ignore this method.

If you prevent ProxyGen.exe from generating a proxy for a host type, the generated type map provider will not add the host type to the type map. You can add the type to the type map by implementing the partial AddCustomTypes method in a separate code file. This enables you to regenerate the type map provider code without affecting your AddCustomTypes implementation.

For an example that demonstrates how to implement the AddCustomTypes method, see Walkthrough: Modifying an Application to Load Add-Ins.

typeToCanonicalName and canonicalToTypeName Fields

These fields contain the underlying data structures for the type map:

  • typeToCanonicalName is a Dictionary<TKey, TValue> that maps Type objects that represent host types (the keys) to canonical names (the values).

  • canonicalToTypeName is a Dictionary<TKey, TValue> that maps canonical names (the keys) to Type objects that represent host types (the values).

HostTypeMapProvider Constructor

This constructor populates the typeToCanonicalName and canonicalToTypeName dictionaries with information from the proxy descriptor file.

GetCanonicalNameForType and GetTypeForCanonicalName Methods

These are the implementations the GetCanonicalNameForType and GetTypeForCanonicalName methods. These methods are called by Visual Studio Tools for Applications to get the host type that is associated with a specified canonical name and to get the canonical name that is associated with a specified host type.

Example

The following code demonstrates a sample type map provider that is generated by ProxyGen.exe. This is the type map provider for the ShapeAppCSharp sample application, with some initialization code removed for brevity. For more information about this sample, see ShapeApp Samples (Visual Studio Tools for Applications).

namespace Microsoft.VisualStudio.Tools.Applications.HostTypeMapProvider
{
    public class HostTypeMapProvider : Microsoft.VisualStudio.Tools.Applications.Runtime.ITypeMapProvider
    {

        partial void AddCustomTypes();

        System.Collections.Generic.Dictionary<System.Type, System.String> typeToCanonicalName = null;
        System.Collections.Generic.Dictionary<System.String, System.Type> canonicalToTypeName = null;

        internal HostTypeMapProvider()
        {
            typeToCanonicalName = new System.Collections.Generic.Dictionary<System.Type, string>();
            canonicalToTypeName = new System.Collections.Generic.Dictionary<string, System.Type>();

            canonicalToTypeName.Add("ShapeApp.Proxy, ShapeApp.Proxy.IDrawing", typeof(ShapeApp.Proxy.IDrawing));
            // Additional canonicalToTypeName initialization code...

            typeToCanonicalName.Add(typeof(ShapeApp.Proxy.IDrawing), "ShapeApp.Proxy, ShapeApp.Proxy.IDrawing");
            // Additional typeToCanonicalName initialization code...

            this.AddCustomTypes();
        }

        public string GetCanonicalNameForType(System.Type type)
        {
            if (typeToCanonicalName.ContainsKey(type))
            {
                return typeToCanonicalName[type];
            }
            return null;
        }

        public System.Type GetTypeForCanonicalName(string canonicalName)
        {
            if (canonicalToTypeName.ContainsKey(canonicalName))
            {
                return canonicalToTypeName[canonicalName];
            }
            return null;
        }
    }
}

See Also

Tasks

Walkthrough: Modifying an Application to Load Add-Ins

Concepts

Implementing Host Services

Exposing Host Objects to Add-Ins

Discovering and Loading Add-Ins

Considerations for Loading Add-Ins

Creating Proxies

Reference

Proxy Generation Tool (ProxyGen.exe)