< back

Plugin Architecture and Customization

The StoreBuilder plugin architecture is uniquely powerful.

Basic Plugin Definition

All StoreBuilder plugins should contain at least one class which inherits from StoreBuilder.Extensibility.Plugin and implements inherited abstract members.

Additionally the plugin assembly should be decorated with a StoreBuilder.Extensibility.PluginAttribute which is used to discover StoreBuilder plugins at runtime efficiently. The attribute reduces the cost of scanning all types in all assemblies at app pool startup, as we only need to scan assemblies decorated with this attribute. This results in faster website startup performance.

public class SamplePlugin : Plugin
{
    internal const string PluginAlias = "sampleplugin";
    internal const string PluginName = "Sample Plugin Friendly Name";

    public override void Initialize()
     {
     }

    public override void Migrate(string connectionStringName)
     { }

    public override void Seed(StorefrontContext context)
     {
     }

    /// <summary>
    /// Gets the plugin alias.
    /// </summary>
    public override string Alias
    {
        get { return PluginAlias; }
    }

    /// <summary>
    /// Gets the plugin name.
    /// </summary>
    public override string Name
    {
        get { return PluginName; }
    }

    public override bool Icon
    {
        get
        {
            try
            {
                return (this.GetEmbeddedResource("icon.png") != null);
            }
            catch (Exception ex)
            {
                StorefrontApplication.Log.Info("Plugin does not have an embedded icon.png", ex);
            }
            return false;
        }
    }
    #endregion
}

Registering Provider Implementations

Any one plugin can optionally contain implementations for one or more core functions of StoreBuilder by implementing "Providers". Common examples include payment gateways implementing StoreBuilder.Providers.PaymentProvider and Shipping Carrier plugins implementing StoreBuilder.Providers.ShippingProvider.

You can register any provider implementation in your plugin's Initialize method. For example:

StorefrontApplication.RegisterPaymentProvider<SamplePaymentProvider>();

Non-code Plugin Resources

Any plugin can contain embedded resources to be used with StoreBuilder. This could be images, javascript, stylesheets, handlebars templates or anything else.

All embedded resources should be contained within a folder named EmbeddedResources within your plugin assembly project.

There is an implicit standard is that if the plugin contains an embedded resource called icon.png it will be used in the administration portal on the plugin admin view. A plugin icon can be helpful for end users to quickly locate the plugin visually within the admin portal.

Working with ThemeEngine

Any plugin can provide some static resources to StoreBuilder ThemeEngine by calling ThemeEngine.ImportResource().ThemeEngine.ImportResource(). It is expected that StoreBuilder plugins should be fully functional "out of the box", but that presentation should be customizable by store owner or implementer of a StoreBuilder based website.

Example of importing static files from a plugin's Embedded Resources:

ThemeEngine.ImportResource(this, "Templates.sb-websitefeedback.hbs");
ThemeEngine.ImportResource(this, "Templates.storebuilder.websitefeedback.js");

This will copy the specified embedded resources into the active StoreBuilder theme, unless the exported files already exist.

When consuming the ThemeEngine resources later, plugins should use the built in ThemeEngine methods for retrieving resources or rendering templates.

Because theme resources are first provided to ThemeEngine and then later requested back from ThemeEngine, it provides the opportunity to customize the presentation of even closed source plugins by editing the handlebars templates or other files the plugin provides/uses.

Fulfilling Requests with Content Finder

Any StoreBuilder plugin can register a ContentFinder implementation with StoreBuilder to handle requests made to the website. This routing abstractabstraction allows plugins to drop into multiple different types of web projects such as a regular ASP.net MVC project or a modified environment such as the Umbraco CMS which has its own routing mechanisms for StoreBuilder to tie into. It also allows plugins to be free of any unnecessary dependencies or web framework references.

Using the Database

Plugins are free to use EntityFramework in parallel with StoreBuilder with their own DataContext.