JD2022-TU1/main/tools/framework/JD.TeaBoxAddinSystem/Addins/AddinManager.cs

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);
}
}
}