ユーザーが構成できるデータベース アプリケーションがあります。これらのオプションのいくつかは、さまざまな外部プラグイン システムから選択しています。
ベース プラグイン タイプがあり、データベース スキーマには同じフィールドを持つ同じプラグイン レコード タイプがあります。アプリケーションの開始時に(IoCコンテナーを介してPlugingMananger
)プラグインをロードし、それらをデータベースにリンクする必要があります(基本的に、ディスク上のプラグインからデータベースにフィールドをコピーします)。
public interface IPlugin
{
Guid Id{ get; }
Version Version { get; }
string Name { get; }
string Description { get; }
}
プラグインは、 を使用して取得できますPlugingMananger.GetPlugin(Guid pluginId, Guid userId)
。ユーザー ID は、プラグイン アクションを呼び出すことができる複数のユーザーのうちの 1 人の ID です。
既知のインターフェイスのセットは、特定の機能 (フォーマッター、外部データ、データ送信者など) に固有のアプリケーションによって事前に宣言されています。プラグインが不明なサービス インターフェイスを実装している場合、それは無視されます。
public interface IAccountsPlugin : IPlugin
{
IEnumerable<SyncDto> GetData();
bool Init();
bool Shutdown();
}
PluginSettingAttribute
プラグインは、マルチユーザー システムでユーザーごとに定義された設定属性を持つこともできます。これらのプロパティは、特定のユーザーに対してプラグインが取得されるときに設定PluginPropertyAttribute
され、すべてのユーザーに共通で、プラグインによって一度だけ読み取り専用に設定されるプロパティに対して設定されます。アプリケーションの起動時にプラグインが登録されたとき。
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. this field will be written to
// when a plugin is retrieved by the plugin manager with the value for the
// requesting user that was retrieved from the database.
[PluginSetting("ExternalSystemUsernameSettingName")]
public string ExternalSystemUsername
{
get { return ExternalSystemUsername }
set { ExternalSystemUsername = value; }
}
// PluginPropertyAttribute will create a row in the attributes table common for all users
[PluginProperty("ShortCodeName")]
public string ShortCode
{
get { return "externaldata"; }
}
public Version PluginVersion
{
get { return new Version(1, 0, 0, 0); }
}
public string PluginName
{
get { return "Data connector"; }
}
public string PluginDescription
{
get { return "Connector for collecting data"; }
}
}
ここに私の質問と私がガイダンスを求めている領域があります:
IoC コンテナー内のプラグインをデータベースにリンクする上記の抽象化により、ユーザーはデータベース フィールドを選択できます
Customer.ExternalAccountsPlugin = idOfExternalPlugin
。これは重く感じます - 他のシステムでこれを実現する簡単な方法はありますか (たとえば、SharePoint にはユーザー データベースによって参照されるプラグインがたくさんあります)。私のアプリケーションは、コンパイル時に、それがサポートするインターフェースを指示し、他のすべてを無視します - 私はいくつかのシステムがオープンなプラグインで完全に拡張可能であると主張しているのを見てきました。再コンパイルせずに将来の更新を発行できるようにする2つのオプションはありますが、具体的なインターフェースを使用しますか?
私のプラグインにはメタデータ (PluginProperty または PluginSetting) が含まれている可能性があり、プラグイン メタデータ テーブル (linq クエリがより複雑になります) またはプラグイン データベース レコード行 (簡単な linq クエリ) に格納するのに最適な場所がわかりません
PluginManager.GetPluginsOfType<IAccounts>.Where(x => x.ShortCode = "externaldata").FirstOrDefault();
。ベストプラクティスとして使用されますか?プラグインの機能とインターフェイスはデータベース スキーマに大きく依存しているため、特定のスキーマ リビジョンで使用するプラグインを制限するには、どのような方法が推奨されますか? このスキーマ リビジョンをデータベースの設定テーブルに 1 行として保持し、リリースごとに手動で更新しますか? プラグインは最大スキーマ バージョンをサポートしますか、それともアプリケーションは既知のプラグイン バージョンのリストをサポートしますか?