Udostępnij za pośrednictwem


Architecture of Generated Proxy Code

To fully understand how add-ins call into the object model of the host application, you must familiarize yourself with the structure of the proxy code that is generated by ProxyGen.exe. If you need to directly modify the generated proxy code, this knowledge can also help prevent you from making breaking changes to the proxy code. For more information about proxies, see Creating Proxies.

ProxyGen.exe generates proxy code for types and members in COM type libraries and managed assemblies in different ways. For more information, see Proxies for COM Type Libraries and Proxies for Managed Assemblies.

The proxy code file contains the following sets of types:

  • Entry points

  • Custom exceptions

  • Other proxy types

  • ProxyServices class

Note

ProxyGen.exe generates all proxy types as partial types. This enables you to extend the types in a separate code file while preserving the code that was generated by ProxyGen.exe.

Entry Points

After you generate a proxy descriptor file, you typically specify at least one entry point in the object model. An entry point is a class that provides direct access to a type in the object model of the host application (also called a host type). The entry point is also instantiated when the host application loads an add-in. For more information, see Defining Entry Points and Other Proxy Changes.

After you specify an entry point and run the proxy descriptor file through ProxyGen.exe, ProxyGen.exe generates two types in the proxy code file:

  • A proxy type that has all of the members of the host type (except for members that were hidden by using the isExcluded attribute in the proxy descriptor file) and additional attributes that are used by Visual Studio Tools for Applications to call into the corresponding host type. For more information about the design of the proxy type, see Other Proxy Types.

  • An entry point class. This class has a name that ends with the suffix EntryPoint (for example, if the original type is named Application, ProxyGen.exe generates an entry point class named ApplicationEntryPoint).

Design of Entry Point Classes

Each entry point class has the following features:

The following code example demonstrates the declaration of an entry point class named ApplicationEntryPoint. This is a simplified version of the code that is generated by ProxyGen.exe.

[System.AddIn.Pipeline.AddInBaseAttribute(
    ActivatableAs = new System.Type[]{typeof(IEntryPoint)})]
public partial class ApplicationEntryPoint : IExtendedEntryPoint
{
    // Class members omitted for brevity.
}

Initialization and Shutdown Methods

Most of the IExtendedEntryPoint methods are implemented to do nothing by default. However, the Initialize method performs the following tasks to initialize the add-in:

  • It obtains the IHostItemProvider implementation from the host application, and calls the GetHostObject(String, String, Object) method to get the object in the host application that corresponds to the entry point. For more information, see Exposing Host Objects to Add-Ins.

  • It gets the IHostTypeProvider implementation that is provided by Visual Studio Tools for Applications, and assigns this object to the static hostTypeProvider field of the ProxyServices class. For more information, see ProxyServices Class.

The following code example demonstrates the Initialize method for an entry point class named ApplicationEntryPoint. This is a simplified version of the code that is generated by ProxyGen.exe.

void Microsoft.VisualStudio.Tools.Applications.Runtime.IEntryPoint.Initialize(System.IServiceProvider serviceProvider)
{
    IHostItemProvider providerHost =
        (IHostItemProvider)serviceProvider.GetService(typeof(IHostItemProvider));

    Microsoft.VisualStudio.Tools.Applications.ProxyServices.Helper.ProxyHelper.hostTypeProvider =
        (IHostTypeProvider)serviceProvider.GetService(typeof(IHostTypeProvider));

    this.remoteObject = providerHost.GetHostObject(this.PrimaryType, this.PrimaryCookie) as Application;
    this.Application = this.remoteObject;

    this.RemoteType = this.RemoteObject.GetType();
    this.InitializeDelayedEvents();
}

Understanding How Entry Points Expose the Object Model of the Host Application

The entry point class provides access to the members of the host type. When add-in developers access the object model of the host application, they use a host item class in their project. The host item derives from the entry point class. For more information about host items, see Creating Project Templates Using the Project Template Generation Tool (Projectgen.exe).

The entry point class exposes the members of the host type by aggregating an instance of the corresponding proxy type. In other words, the entry point does the following:

  • It stores an instance of the proxy type as a protected field.

  • It has its own versions of all of the non-static members of the proxy type. All of these members simply call through to the corresponding member of the proxy object stored in the field.

For example, if ProxyGen.exe generates an entry point class named ApplicationEntryPoint and a corresponding proxy type named Application, then the ApplicationEntryPoint class also has an Application field that returns an instance of the Application proxy type. Both the ApplicationEntryPoint class and the Application proxy type share the same set of non-static members that are defined by the host type. However, each member of the ApplicationEntryPoint class simply calls the corresponding member of the ApplicationEntryPoint.Application field.

Host Members Not Generated in the Entry Point Class

There are two sets of host members that are not generated in the entry point class:

  • Static members.

  • Members that the host type inherits from other types.

To access a static member, the add-in developer must use the proxy type that is associated with the entry point class. For example, if a host type named Application has a static method named CreateColor, then ProxyGen.exe will not add this method to the ApplicationEntryPoint class. To access this method, the add-in developer must call the static CreateColor method of the Application proxy type.

To access a member that the host type inherits from a base type, the add-in developer must use the field of the aggregated proxy type in the host item. For example, if a host type named Application inherits a property named WindowHandle, then ProxyGen.exe will not add this property to the ApplicationEntryPoint class, and therefore the host item in the add-in project will not have the WindowHandle property. To access this property from a host item class named AppAddIn, an add-in developer must call the WindowHandle property of the AppAddIn.Application field.

Custom Exceptions

If you are generating proxies for a managed object model that defines one or more custom exceptions, ProxyGen.exe generates a partial definition of each exception in the proxy code file. ProxyGen.exe does not generate proxy code for exception members that are used for serialization, or for any other members that might have executable code. You must define these missing members of the generated proxy exception yourself. For more information, see Creating Proxies for Custom Exceptions.

ProxyGen.exe generates only the following exception members:

  • The parameterless constructor.

  • The constructor that takes a single message string parameter.

  • Fields.

ProxyGen.exe does not generate the following members:

  • The override of the GetObjectData method.

  • The serialization constructor (that is, the constructor that has SerializationInfo and StreamingContext parameters).

  • Any other constructors.

  • Any properties that wrap fields in the exception.

Other Proxy Types

Proxy types that are not an entry point class or an exception have the HostTypeAttribute applied to them. This attribute specifies the canonical name of the type in the host application that the proxy type is associated with. When an add-in uses a proxy type, the canonical name is used by Visual Studio Tools for Applications to identify and call into the corresponding type in the host application. For more information, see Mapping Host Types to Proxy Types.

The proxy types have additional characteristics that depend on whether the corresponding host type is a class, interface, or some other item. For more information, see Proxies for COM Type Libraries and Proxies for Managed Assemblies.

The proxy types contain all public members and explicitly implemented members of the host type. Static and non-static members have different characteristics.

Non-Static Members

Non-static members of proxy types are never executed by add-ins. These members throw a NotImplementedException by default. When an add-in calls one of these members, Visual Studio Tools for Applications uses attributes to identify and call the corresponding member in the host application.

ProxyGen.exe applies the following attributes to non-static members:

  • HostMemberAttribute is applied to every non-static proxy member except for events (for properties, this attribute is applied to the get or set accessors). This attribute specifies the name of the corresponding member in the host application and the binding flags.

  • HostEventAttribute is applied to events of proxy types for a COM object model. This attribute specifies the dispatch ID of the COM event.

Static Members

Static members of proxy types do not have the HostMemberAttribute applied to them. Instead, they contain executable code that remotely calls into the corresponding member in the host application. This code uses the ProxyServices class to do this.

ProxyServices Class

The ProxyServices class is a helper class in the proxy code file that is used by static members of proxy types. The ProxyServices class provides a single static field named hostTypeProvider. This field returns an IHostTypeProvider implementation that is used by static members to call into their corresponding members in the host application. Visual Studio Tools for Applications provides an internal implementation of the IHostTypeProvider interface, so you do not need to implement this interface yourself.

The hostTypeProvider field is initialized by the Initialize method of the entry point class.

See Also

Concepts

Creating Proxies

Defining Entry Points and Other Proxy Changes

ProxyGen Descriptor Schema Reference

Reference

Proxies for COM Type Libraries

Proxies for Managed Assemblies

Proxy Generation Tool (ProxyGen.exe)