-
Notifications
You must be signed in to change notification settings - Fork 96
Data Files and Resources
Home > Programming Guide > Data Files and Resources |
---|
In the previous section we've seen how to use an extension point for registering extension data. Using attribute/value pairs is useful for simple metadata, but it may not be enough for more complex data. For example, let's say we are implementing a text editor and we want to allow add-ins to provide their own document templates. Each template will have a name, an icon and a text document with the template text. This extension point could be declared like this:
using System;
using Mono.Addins;
[assembly:ExtensionPoint ("/DocumentTemplates", ExtensionAttributeType=typeof(DocumentTemplateAttribute))]
public class DocumentTemplateAttribute: Attribute
{
public DocumentTemplateAttribute ()
{
}
[NodeAttribute]
public string Name { get; set; }
[NodeAttribute]
public string IconResource { get; set; }
[NodeAttribute]
public string TemplateResource { get; set; }
}
Notice that using the 'Resource' suffix in the property names is just a convention.
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:DocumentTemplate (Name="Letter", IconResource="LetterIcon.png", TemplateResource="Letter.txt")}
[assembly:DocumentTemplate (Name="Fax", IconResource="FaxIcon.png", TemplateResource="Fax.txt")}
The add-in would embed the following files as resources in the add-in assembly: LetterIcon.png, FaxIcon.png, Letter.txt and Fax.txt.
Those extensions could be retrieved by the host application like this:
using System;
using Mono.Addins;
[assembly:AddinRoot ("HelloWorld", "1.0")]
class MainClass
{
public static void Main ()
{
AddinManager.Initialize ();
AddinManager.Registry.Update ();
foreach (ExtensionNode<DocumentTemplateAttribute> node in AddinManager.GetExtensionNodes ("/DocumentTemplates")) {
Console.WriteLine ("Loading template: {0}", node.Data.Name);
// Load the icon
Stream iconStream = node.Addin.GetResource (node.Data.IconResource);
Bitmap icon = new Bitmap (iconStream);
iconStream.Close ();
// Load the template
Stream templateStream = node.Addin.GetResource (node.Data.TemplateResource);
StreamReader sr = new StreamReader (templateStream);
string templateText = sr.ReadtoEnd ();
sr.Close ();
// ... do something with 'icon' and 'templateText'
}
}
}
The Addin property of the ExtensionNode class returns an object of type Mono.Addins.RuntimeAddin which can be used to get resources and other kinds of data from the add-in assembly.
The GetResource() method is used in the example to get the stream of a resource.
Instead of embedding data files as resources, it is also possible to deploy them as standalone files. The same example, using standalone files, would look like this:
using System;
using Mono.Addins;
[assembly:ExtensionPoint ("/DocumentTemplates", ExtensionAttributeType=typeof(DocumentTemplateAttribute))]
public class DocumentTemplateAttribute: Attribute
{
public DocumentTemplateAttribute ()
{
}
[NodeAttribute]
public string Name { get; set; }
[NodeAttribute]
public string IconFile { get; set; }
[NodeAttribute]
public string TemplateFile { get; set; }
}
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:DocumentTemplate (Name="Letter", IconFile="LetterIcon.png", TemplateFile="Letter.txt")}
[assembly:DocumentTemplate (Name="Fax", IconFile="FaxIcon.png", TemplateFile="Fax.txt")}
In this case, the included files would not be embedded as resources, but instead provided together with the add-in assembly. The path provided in IconFile and TemplateFile should be relative to the add-in assembly.
Those extensions could be retrieved by the host application like this:
using System;
using Mono.Addins;
[assembly:AddinRoot ("HelloWorld", "1.0")]
class MainClass
{
public static void Main ()
{
AddinManager.Initialize ();
AddinManager.Registry.Update ();
foreach (ExtensionNode<DocumentTemplateAttribute> node in AddinManager.GetExtensionNodes ("/DocumentTemplates")) {
Console.WriteLine ("Loading template: {0}", node.Data.Name);
// Load the icon
Stream iconStream = File.OpenRead (node.Addin.GetFilePath (node.Data.IconFile));
Bitmap icon = new Bitmap (iconStream);
iconStream.Close ();
// Load the template
StreamReader sr = new StreamReader (node.Addin.GetFilePath (node.Data.TemplateFile));
string templateText = sr.ReadtoEnd ();
sr.Close ();
// ... do something with 'icon' and 'templateText'
}
}
}
Given a relative file name, the GetFilePath() method returns the corresponding absolute path.
Next topic: About Lazy Loading
- Extension Points and Extensions
- Querying Extension Points
- Type Extension Metadata
- Data-only Extension Points
- Data Files and Resources
- About Lazy Loading
- Thread Safety
- The Add-in Registry
- Addin Discovery
- Creating and Managing Add-in Packages
- Advanced Concepts