294 lines
9.5 KiB
C#
294 lines
9.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using JD.Kernel.Classes;
|
|
using JD.Kernel.StaticHelpers;
|
|
using JD.LogService;
|
|
using JD.TeaBoxAddinSystem.Addins.Description;
|
|
using JD.TeaBoxAddinSystem.Addins.Description.Conditions;
|
|
using JD.TeaBoxAddinSystem.Addins.Internal;
|
|
|
|
namespace JD.TeaBoxAddinSystem.Addins
|
|
{
|
|
/// <summary>
|
|
/// Addin Manager.
|
|
/// </summary>
|
|
public static class AddinManager
|
|
{
|
|
private static readonly object m_lock = new object();
|
|
private static readonly AddinSessionService m_sessionService = new AddinSessionService();
|
|
private static readonly List<ILogger> m_loggers = new List<ILogger>();
|
|
private static Implementation m_implementation = new Implementation();
|
|
|
|
/// <summary>
|
|
/// Loggers can listen to addin events as well as addin loading errors.
|
|
/// </summary>
|
|
public static IList<ILogger> Loggers
|
|
{
|
|
get
|
|
{
|
|
return m_loggers;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Loaded addins.
|
|
/// </summary>
|
|
public static ICollection<Addin> LoadedAddins
|
|
{
|
|
get
|
|
{
|
|
return SessionService.LoadedAddins;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Loaded Extension Type Sets.
|
|
/// </summary>
|
|
public static IReadOnlyDictionary<string, ExtensionTypeSet> ExtensionTypeSets
|
|
{
|
|
get
|
|
{
|
|
return SessionService.ExtensionTypeSets;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Loaded Condition Types.
|
|
/// </summary>
|
|
public static IReadOnlyDictionary<string, ConditionType> ConditionTypes
|
|
{
|
|
get
|
|
{
|
|
return SessionService.ConditionTypes;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Loaded extension points.
|
|
/// </summary>
|
|
public static IReadOnlyDictionary<string, ExtensionPoint> ExtensionPoints
|
|
{
|
|
get
|
|
{
|
|
return SessionService.ExtensionPoints;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extension tree.
|
|
/// </summary>
|
|
public static TreeNode ExtensionTree
|
|
{
|
|
get
|
|
{
|
|
return SessionService.ExtensionTree;
|
|
}
|
|
}
|
|
|
|
internal static AddinSessionService SessionService
|
|
{
|
|
get
|
|
{
|
|
return m_sessionService;
|
|
}
|
|
}
|
|
|
|
static AddinManager()
|
|
{
|
|
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns whether the given <paramref name="addin"/> is loaded.
|
|
/// </summary>
|
|
/// <param name="addin"></param>
|
|
/// <returns></returns>
|
|
public static bool IsAddinLoaded(Addin addin)
|
|
{
|
|
return SessionService.IsAddinLoaded(addin);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns whether the given <paramref name="module"/> is loaded.
|
|
/// </summary>
|
|
/// <param name="module"></param>
|
|
/// <returns></returns>
|
|
public static bool IsModuleLoaded(Module module)
|
|
{
|
|
return SessionService.IsModuleLoaded(module);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Loads the given <paramref name="addin"/>.
|
|
/// </summary>
|
|
/// <param name="addin"></param>
|
|
public static bool LoadAddin(Addin addin)
|
|
{
|
|
return SessionService.LoadAddin(addin);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unloads the given <paramref name="addin"/>.
|
|
/// </summary>
|
|
/// <param name="addin"></param>
|
|
public static bool UnloadAddin(Addin addin)
|
|
{
|
|
return SessionService.UnloadAddin(addin);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unloads all the loaded <see cref="Addin"/>s.
|
|
/// </summary>
|
|
public static void UnloadAllAddins()
|
|
{
|
|
UnloadAllAddins(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unloads all the loaded <see cref="Addin"/>s. Used for tests mostly.
|
|
/// </summary>
|
|
/// <param name="destroyHandlers">Whether to destroy event handlers.</param>
|
|
public static void UnloadAllAddins(bool destroyHandlers)
|
|
{
|
|
SessionService.UnloadAllAddins(destroyHandlers);
|
|
}
|
|
|
|
/// <summary>
|
|
/// This method will reevaluate all the loaded <see cref="PolledConditionNode"/>s.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Call this periodically in your application. The more frequent the better but
|
|
/// there's a performance cost associated with it.
|
|
/// </remarks>
|
|
public static void ReevaluatePolledConditionNodes()
|
|
{
|
|
SessionService.ConditionManager.ReevaluatePolledConditionNodes();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets an extension node at the given <paramref name="path"/>.
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
/// <returns></returns>
|
|
public static ExtensionNode GetExtensionNode(string path)
|
|
{
|
|
TreeNode node = ExtensionTree[path];
|
|
|
|
if (node == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return node.ExtensionNode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a list of extension nodes at the given <paramref name="path"/> with type <typeparamref name="T"/>.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This method returns only the objects of type <typeparamref name="T"/> and ignores other nodes.
|
|
/// </remarks>
|
|
/// <typeparam name="T">Type of extension nodes.</typeparam>
|
|
/// <param name="path"></param>
|
|
/// <returns>A non null list of extension nodes of type <typeparamref name="T"/>. List may be empty if the path does not exist.</returns>
|
|
public static IEnumerable<T> GetExtensionNodes<T>(string path) where T : ExtensionNode
|
|
{
|
|
return m_implementation.GetExtensionNodes<T>(path);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a list of extension objects at a given <paramref name="path"/>.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Returns an empty collection when path does not exists.
|
|
/// </remarks>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="path"></param>
|
|
/// <returns></returns>
|
|
public static IList<T> GetExtensionObjects<T>(string path)
|
|
{
|
|
return m_implementation.GetExtensionObjects<T>(path);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new list of extension objects from the given <paramref name="path"/>.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This method returns only the objects of type <typeparamref name="T"/> and ignores other created objects.
|
|
/// </remarks>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="path"></param>
|
|
/// <returns></returns>
|
|
public static IEnumerable<T> CreateExtensionObjects<T>(string path) where T : class
|
|
{
|
|
ExtensionNode node = GetExtensionNode(path);
|
|
|
|
if (node == null)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
foreach (ExtensionNode childNode in node.ChildNodes)
|
|
{
|
|
object extensionObject = childNode.CreateExtensionObject();
|
|
if (!(extensionObject is T))
|
|
{
|
|
throw new ArgumentException(
|
|
$"Extension node {childNode.FullPath} created object {extensionObject} which is not of the expected type {typeof(T).Name}");
|
|
}
|
|
|
|
yield return (T)extensionObject;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Registers the given <paramref name="handler"/> on the <see cref="ExtensionNode"/> at the given <paramref name="path"/>.
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
/// <param name="handler"></param>
|
|
public static void AddExtensionChangedHandler(string path, EventHandler<ExtensionNodeChangedEventArgs> handler)
|
|
{
|
|
SessionService.AddExtensionChangedHandler(path, handler);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unregisters the given <paramref name="handler"/> on the <see cref="ExtensionNode"/> at the given <paramref name="path"/>.
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
/// <param name="handler"></param>
|
|
public static void RemoveExtensionChangedHandler(string path, EventHandler<ExtensionNodeChangedEventArgs> handler)
|
|
{
|
|
SessionService.RemoveExtensionChangedHandler(path, handler);
|
|
}
|
|
|
|
/// <summary>
|
|
/// For testing purposes, let swap the implementation.
|
|
/// </summary>
|
|
public static IDisposable UseMockImplementation(Implementation implementation)
|
|
{
|
|
Throw.IfNull(implementation, "implementation");
|
|
|
|
m_implementation = implementation;
|
|
return new DisposableHelper(delegate
|
|
{
|
|
m_implementation = new Implementation();
|
|
});
|
|
}
|
|
|
|
public static Image GetImage(string imageName)
|
|
{
|
|
return m_implementation.GetImage(imageName);
|
|
}
|
|
|
|
internal static void Log(LogEvent @event)
|
|
{
|
|
m_loggers.ForEach(logger => logger.Log(@event));
|
|
}
|
|
|
|
private static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
|
|
{
|
|
return SessionService.GetAssembly(args.Name);
|
|
}
|
|
}
|
|
}
|