using Disco.Models.UI; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Web; using System.Web.Mvc; namespace Disco.Services.Plugins.Features.UIExtension { public static class UIExtensions { private const string ViewDataKey = "___DiscoUIExtensionResults"; // Warning: No type-safety, validate types before updating private static Dictionary> _registrations = new Dictionary>(); private static List GetUIModelRegistrations() where UIModel : BaseUIModel { Type uiModelType = typeof(UIModel); if (!_registrations.TryGetValue(uiModelType, out var modelRegistrations)) { lock (_registrations) { if (!_registrations.TryGetValue(uiModelType, out modelRegistrations)) { modelRegistrations = new List(); _registrations.Add(uiModelType, modelRegistrations); } } } return modelRegistrations; } public static void ExecuteExtensions(ControllerContext context, UIModel model) where UIModel : BaseUIModel { var uiExts = UIExtensions.GetRegisteredExtensions(); Queue uiExtResults = new Queue(); foreach (var uiExt in uiExts) { using (var uiExtInstance = uiExt.CreateInstance>()) { uiExtInstance.Context = context; uiExtResults.Enqueue(uiExtInstance.ExecuteAction(context, model)); } } context.Controller.ViewData[ViewDataKey] = uiExtResults; } public static void ExecuteExtensionResult(WebViewPage page) { Queue uiExtResults = page.ViewData[ViewDataKey] as Queue; if (uiExtResults != null && uiExtResults.Count > 0) { page.WriteLiteral(""); page.WriteLiteral("\n
"); foreach (var uiExtResult in uiExtResults) { string extensionDescription = HttpUtility.HtmlEncode($"{uiExtResult.Source.Id} @ {uiExtResult.Source.PluginManifest.Id} v{uiExtResult.Source.PluginManifest.Version.ToString(4)}"); page.WriteLiteral($"\n\n"); uiExtResult.ExecuteResult(page); page.WriteLiteral($"\n"); } page.WriteLiteral("\n
"); page.WriteLiteral("\n"); } } public static ReadOnlyCollection GetRegisteredExtensions() where UIModel : BaseUIModel { List modelRegistrations = GetUIModelRegistrations(); return new ReadOnlyCollection(modelRegistrations); } internal static bool ExtensionRegistered(UIExtensionFeature Extension) where UIModel : BaseUIModel { List modelRegistrations = GetUIModelRegistrations(); return modelRegistrations.Contains(Extension.Manifest); } internal static bool RegisterExtension(UIExtensionFeature Extension) where UIModel : BaseUIModel { List modelRegistrations = GetUIModelRegistrations(); lock (modelRegistrations) { if (!modelRegistrations.Contains(Extension.Manifest)) { modelRegistrations.Add(Extension.Manifest); return true; } } return false; } internal static bool UnregisterExtension(UIExtensionFeature Extension) where UIModel : BaseUIModel { List modelRegistrations = GetUIModelRegistrations(); lock (modelRegistrations) { if (modelRegistrations.Contains(Extension.Manifest)) { modelRegistrations.Remove(Extension.Manifest); return true; } } return false; } } }