Querying Extension Points

The AddinManager class provides several methods which can be used to query extension points, which are described below. It is important to follow a basic rule:

Extension points can only be queried by the assemblies that declare them
That is, if you use AddinManager.GetExtensionObjects<ICommand>() to get the list of registered commands, the definition of the ICommand interface must be done in the same assembly.

Shared and non-Shared Objects

In the previous section, the AddinManager.GetExtensionObjects() method was used to get a list of objects registered in an extension point. By default, GetExtensionObjects() will always return the same set of instances for a given type, but it has an optional reuseInstances parameter which can be used to change this behavior. Here is an example:

using System;
using Mono.Addins;

[assembly:AddinRoot ("HelloWorld", "1.0")]

class MainClass
{
	public static void Main ()
	{
		AddinManager.Initialize ();
		AddinManager.Registry.Update ();

		// This first loop will create instances of each type registered in the extension point
		foreach (ICommand cmd in AddinManager.GetExtensionObjects<ICommand> (true))
			cmd.Run ();

		// The second loop will reuse and return the same instances created in the previous loop
		foreach (ICommand cmd in AddinManager.GetExtensionObjects<ICommand> (true))
			cmd.Run ();

		// This loop will create new instances, since the 'reuseInstances' parameter is set to false
		foreach (ICommand cmd in AddinManager.GetExtensionObjects<ICommand> (false))
			cmd.Run ();
	}
}

Extension Nodes

The AddinManager class takes care of locating and loading the add-ins that provide extensions, and creates the instances for each registered type.

It is possible to have more control on the object creation by using the AddinManager.GetExtensionNodes() method. This method returns a list of TypeExtensionNode objects, which can be used to lazily create the objects. Here is an example:

using System;
using Mono.Addins;

[assembly:AddinRoot ("HelloWorld", "1.0")]

class MainClass
{
	public static void Main (string[] args)
	{
		AddinManager.Initialize ();
		AddinManager.Registry.Update ();
		
		foreach (TypeExtensionNode node in AddinManager.GetExtensionNodes (typeof(ICommand))) {
			ICommand cmd = node.CreateInstance ();
			cmd.Run ();
		}
	}
}

In this example, we get all extension nodes registered for the ICommand extension point. Using the node, we can create instances of the registered types.

By using AddinManager.GetExtensionNodes() it is possible to delay the creation of extension objects until really necessary. It is important to notice that not only the creation of the object will be delayed, but also the loading of the add-ins extending that extension point.

More Information

The Handling Add-ins at Run-time section has more information about how to query extension points.

Next topic: Type Extension Metadata

Last edited May 20, 2010 at 6:59 PM by slluis, version 3

Comments

slluis Jul 1, 2010 at 6:59 PM 
The limitation applies to all methods for querying extension points, including all GetExtensionObject* and GetExtensionNode* methods.

Montellese Jun 18, 2010 at 7:47 PM 
Does the limitation of being able to query extension points only from within the assembly who declares them only affect AddinManager.GetExtensionObjects<ICommand>() or does it also apply to the non-generic versions of the AddinManager.GetExtensionObjects() methods?