I have a database application that is configurable by the user - some of these options are selecting from different external plugin systems.

I have a base Plugin type, my database schema has the same Plugin record type with the same fields. I have a PlugingMananger to load plugins (via an IoC container) at application start and link them to the database (essentially copies the fields form the plugin on disk to the database).

public interface IPlugin
{
    Guid Id{ get; }
    Version Version { get; }
    string Name { get; }
    string Description { get; }
}

Plugins can then be retrieved using PlugingMananger.GetPlugin(Guid pluginId, Guid userId), where the user ID is that of the one of the multiple users who a plugin action may be called for.

A set of known interfaces have been declared by the application in advance each specific to a certain function (formatter, external data, data sender etc), if the plugin implements a service interface which is not known then it will be ignored:

public interface IAccountsPlugin : IPlugin
{
    IEnumerable<SyncDto> GetData();
    bool Init();
    bool Shutdown();
}

Plugins can also have settings attributes PluginSettingAttribute defined per user in the multi-user system - these properties are set when a plugin is retrieved for a specific user, and a PluginPropertyAttribute for properties which are common across all users and read-only set by the plugin one time when the plugin is registered at application startup.

public class ExternalDataConnector : IAccountsPlugin
{
    public IEnumerable<AccountSyncDto> GetData() { return null; }
    public void Init() { }
    public void Shutdown() { }

    private string ExternalSystemUsername;
    // PluginSettingAttribute will create a row in the settings table, settingId
    // will be set to provided constructor parameter. 
Edit
Report