Dynamic Plugin Quickstart

'''NOTE: This tutorial now refers to a very old OpenSimulator and so is only partially useful. See IRegionModule for something more up to date.'''

A quick guide to writing plugins. Please refer to How to create a dynamic plugin for more in-depth information.

Defining Extension Points
Extension points describe the location in the program where external modules can be plugged-in at runtime. Extension points can be defined in one of two ways:


 * decorating interfaces, classes or methods with attributes in the source code
 * embedding an XML file, called a manifest, as a resource in an assembly

In OpenSim, the preferred method is to embed an XML manifest in the assembly. Below is an example manifest defining one extension point in the AssetInventoryServer:

This manifest contains the following elements:


 * Addin
 * id: an identifier describing this addin, used for dependencies in other addins.
 * isroot: set to true if this manifest does not define any extension nodes, otherwise can be left out completely.
 * version: a version number, also used for dependencies in other addins.
 * Runtime: a list of assemblies that need to be imported by Mono.Addins as it builds the plugin repository. In the example, the  assembly contains the definition for   interface, while   contains a definition for.
 * ExtensionPoint
 * path: the location of the extension point in the extension point tree (see Extension Paths).
 * ExtensionNode
 * name: a name describing this extension node.
 * type: a class that handles plugin loading, this should probably be  unless you know what you're doing.
 * objectType: an instance of this object will be loaded into this extension point at runtime. This is probably what your plugin will instantiate/subclass/implement.

At this stage, all that is needed is  defined and present in.

PLEASE NOTE: embedding XML manifests in .exe assemblies doesn't work. The .addin.xml file must reside in a directory that Mono.Addins will scan for plugins. Currently in OpenSimulator this is the current working directory. Ideally all applications would consist of an .exe assembly and a .dll assembly which contains the embedded XML manifest.

Defining Extensions
Extensions that implement extension points are defined in a similar way. Below is an example corresponding XML file describing a plugin for the above extension point:

The elements (not in the same order as in the file) are:


 * Addin
 * id: a string identifying this plugin, can be used for dependencies in other plugins.
 * version: a version of this plugin, also used for dependencies in other plugins.
 * Runtime: a list of assemblies to import at runtime while Mono.Addins builds up the plugin registry. In this case,  contains the definition for , and   contains a definition for.
 * Dependencies: describes other addin(s) required to be loaded before this addin can be loaded. The id and version is used.
 * Extension
 * path: the path along the extension point tree to the extension point which this extension implements.
 * Plugin
 * id: a string identifying this particular extension. Pretty much an arbitrary string.
 * provider: another property of the extension, which can be an arbitrary string. In OpenSim, the convention seems to be to place the assembly name here which contains this plugin.
 * type: the fully qualified class name to be instantiated which implements the extension. In the code, this class will inherit from/implement the class/interface specified in objectType attribute of the ExtensionPath.
 * NOTE: this XML file also defines another extension point, meaning that this plugin also takes another plugin. Note the isroot attribute in the topmost Addin element is omitted.

Source Code
The relevant code which ends up in  and loads the AssetStorage plugin looks something like this:

The  class lives in  ; have a look through the code for more plugin loading options.