Data-only Extension Points

Extension data doesn't always need to be type metadata. Mono.Addins also supports data-only extension points. Applications are composed by code and by data. Type extensions points allow extending the code, data extension points allow extending data. For example, a word processor application could declare an extension point for registering document templates, or the main menu could be declared as an extensible data structure. Mono.Addins offers a common API and extension model for all kinds of extensions.

Extension data can be specified using custom attributes, but it is also possible to use XML as explained in following chapters. For now, we'll stick to custom attributes.

Declaring a Data-only Extension Point

Here is an example of how to declare a data extension point:

using System;
using Mono.Addins;

[assembly:ExtensionPoint ("/HelloWorld/WelcomeMessages", ExtensionAttributeType=typeof(WelcomeMessageAttribute))]

public class WelcomeMessageAttribute: Attribute
{
	public WelcomeMessageAttribute ([NodeAttribute ("Text")] string text)
	{
		Text = text;
	}

	[NodeAttribute]
	public string Text { get; set; }
}

The [ExtensionPoint] attribute can be used at assembly level to declare a data-only extension point. The first parameter of the attribute is the Path of the extension point. The path is like an identifier of the extension point. It starts with a slash and can contain several identifiers separated by slashes, like a file system path (although it is not bound to a real file system path, it is just an identifier).

The ExtensionAttributeType property can be used to specify the custom attribute to be used to declare the extensions. The specified custom attribute must follow the rules explained in the Type Extension Metadata section.

Declaring Data Extensions

An add-in extending the above extension point would look like this:

using System;
using Mono.Addins;

[assembly:Addin]
[assembly:AddinDependency ("HelloWorld", "1.0")]

[assembly:WelcomeMessage ("Some message")]
[assembly:WelcomeMessage ("Another message")]


The above example declares two extensions of the /HelloWorld/WelcomeMessages extension point.

Querying Data Extension Points

The main application can query the data extension point using AddinManager.GetExtensionNodes():

using System;
using Mono.Addins;

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

class MainClass
{
	public static void Main ()
	{
		AddinManager.Initialize ();
		AddinManager.Registry.Update ();
		
		foreach (ExtensionNode<WelcomeMessageAttribute> node in AddinManager.GetExtensionNodes ("/HelloWorld/WelcomeMessages")) {
			Console.WriteLine ("Message: " + node.Data.Text);
		}
	}
}

When querying a data-only extension point bound to a custom extension attribute, the AddinManager.GetExtensionNodes() will return nodes of type ExtensionNode<T>, where T is the type of the custom extension attribute. This class has a Data property which contains the instance of the custom attribute with the extension data.

Next topic: Data Files and Resources

Last edited Jan 24 at 2:08 PM by slluis, version 6

Comments

slluis Dec 6, 2011 at 8:31 PM 
Fixed. Thanks!

AleckAgakhan Dec 5, 2011 at 10:24 PM 
Just some typoes:

[assembly:ExtensionPoint ("/HelloWorld/WelcomeMessages", ExtensionAttributeType=typeof(MessageAttribute))]
must be
[assembly:ExtensionPoint ("/HelloWorld/WelcomeMessages", ExtensionAttributeType=typeof(WelcomeMessageAttribute))]

foreach (ExtensionNode<CommandAttribute> node in AddinManager.GetExtensionNodes ("/HelloWorld/WelcomeMessages"))
must be
foreach (ExtensionNode<WelcomeMessageAttribute> node in AddinManager.GetExtensionNodes ("/HelloWorld/WelcomeMessages"))