To expose an object in your add-in to other solutions, perform the following steps in your add-in:
Define a class that you want to expose to other solutions. At a minimum, this class must be public, it must have the ComVisibleAttribute attribute set to true, and it must expose the IDispatch interface.
Override the RequestComAddInAutomationService method in the ThisAddIn class. Return the object that you want to expose to other solutions.
The following code example demonstrates how to override RequestComAddInAutomationService. This example assumes that you have defined a class named AddInUtilities that you want to expose to other solutions. To see this code in the context of a larger walkthrough, see Walkthrough: Calling Code in an Application-Level Add-in from VBA.
Private utilities As AddInUtilities
Protected Overrides Function RequestComAddInAutomationService() As Object
If utilities Is Nothing Then
utilities = New AddInUtilities()
End If
Return utilities
End Function
private AddInUtilities utilities;
protected override object RequestComAddInAutomationService()
{
if (utilities == null)
utilities = new AddInUtilities();
return utilities;
}
When your add-in is loaded, the Visual Studio Tools for Office runtime calls the RequestComAddInAutomationService method. The runtime assigns the returned object to the Object property of a COMAddIn object that represents your add-in. This COMAddIn object is available to other Office solutions, and to solutions that automate Office.
The requirements for exposing the IDispatch interface in your exposed object is different for VBA clients and non-VBA clients. There are also additional requirements to expose your object to out-of-process clients.
Exposing IDispatch to VBA Solutions
There are several ways the object in your add-in can expose the IDispatch interface to VBA solutions. Typically, the recommended way is to perform the following steps:
Define an interface that declares the methods you want to expose to other solutions.
Apply the ComVisibleAttribute attribute to this interface, and set this attribute to true.
Modify your class to implement this interface.
Apply the ClassInterfaceAttribute attribute to your class, and set this attribute to the value None.
The following code example demonstrates how to define a class that exposes the IDispatch interface. To see this code in the context of a larger walkthrough, see Walkthrough: Calling Code in an Application-Level Add-in from VBA.
<ComVisible(True)> _
Public Interface IAddInUtilities
Sub ImportData()
End Interface
<ComVisible(True)> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class AddInUtilities
Implements IAddInUtilities
' This method tries to write a string to cell A1 in the active worksheet.
Public Sub ImportData() Implements IAddInUtilities.ImportData
Dim activeWorksheet As Excel.Worksheet = Globals.ThisAddIn.Application.ActiveSheet
If activeWorksheet IsNot Nothing Then
Dim range1 As Excel.Range = activeWorksheet.Range("A1")
range1.Value2 = "This is my data"
End If
End Sub
End Class
[ComVisible(true)]
public interface IAddInUtilities
{
void ImportData();
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class AddInUtilities : IAddInUtilities
{
// This method tries to write a string to cell A1 in the active worksheet.
public void ImportData()
{
Excel.Worksheet activeWorksheet = Globals.ThisAddIn.Application.ActiveSheet as Excel.Worksheet;
if (activeWorksheet != null)
{
Excel.Range range1 = activeWorksheet.get_Range("A1", System.Type.Missing);
range1.Value2 = "This is my data";
}
}
}
When you perform these steps, VBA code can call only the methods that you declare in the interface. VBA code cannot call any other methods in your class, including methods that your class obtains from base classes such as Object.
You can alternatively expose the IDispatch interface by applying the ClassInterfaceAttribute attribute to the class, and by setting this attribute to the value AutoDispatch or AutoDual. If you do this, you do not have to declare the methods in a separate interface. However, VBA code can call any public and non-static methods in your class, including methods obtained from base classes such as Object.
Exposing IDispatch to Non-VBA Solutions
If you want to expose an object in your add-in to non-VBA solutions, such as other Visual Studio Tools for Office add-ins, you must perform the following steps to ensure that your object exposes the IDispatch interface:
Define an interface that declares the methods you want to expose to other solutions. Other solutions can call only the methods that you declare in this interface.
Apply the ComVisibleAttribute attribute to this interface, and set this attribute to true.
Modify your class to implement this interface.
Apply the ClassInterfaceAttribute attribute to your class, and set this attribute to the value None.
Build your add-in project with the Register for COM interop option. For more information, see How to: Register a Component for COM Interop.
Avoiding a Race Condition in Out-of-Process Clients
If you want to expose an object in your add-in to out-of-process clients, follow the steps listed above to expose the IDispatch interface to non-VBA solutions. However, to ensure that out-of-process clients can call your exposed add-in object, your class must also derive from StandardOleMarshalObject.
Otherwise, attempts to get an instance of your exposed object in an out-of-process client might fail unexpectedly. This is because all calls into the object model of an Office application must be made on the main UI thread, but calls from an out-of-process client to your object will arrive on an arbitrary RPC (remote procedure call) thread. The COM marshaling mechanism in the .NET Framework will not switch threads, and it will instead attempt to marshal the call to your object on the incoming RPC thread instead of the main UI thread.
If your object is an instance of a class that derives from StandardOleMarshalObject, incoming calls to your object are automatically marshaled to the thread where the exposed object was created, which will be the main UI thread of the host application.
For more information about using threads in Visual Studio Tools for Office solutions, see Threading Support in Office.