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
{
///
/// Addin Manager.
///
public static class AddinManager
{
private static readonly object m_lock = new object();
private static readonly AddinSessionService m_sessionService = new AddinSessionService();
private static readonly List m_loggers = new List();
private static Implementation m_implementation = new Implementation();
///
/// Loggers can listen to addin events as well as addin loading errors.
///
public static IList Loggers
{
get
{
return m_loggers;
}
}
///
/// Loaded addins.
///
public static ICollection LoadedAddins
{
get
{
return SessionService.LoadedAddins;
}
}
///
/// Loaded Extension Type Sets.
///
public static IReadOnlyDictionary ExtensionTypeSets
{
get
{
return SessionService.ExtensionTypeSets;
}
}
///
/// Loaded Condition Types.
///
public static IReadOnlyDictionary ConditionTypes
{
get
{
return SessionService.ConditionTypes;
}
}
///
/// Loaded extension points.
///
public static IReadOnlyDictionary ExtensionPoints
{
get
{
return SessionService.ExtensionPoints;
}
}
///
/// Extension tree.
///
public static TreeNode ExtensionTree
{
get
{
return SessionService.ExtensionTree;
}
}
internal static AddinSessionService SessionService
{
get
{
return m_sessionService;
}
}
static AddinManager()
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
///
/// Returns whether the given is loaded.
///
///
///
public static bool IsAddinLoaded(Addin addin)
{
return SessionService.IsAddinLoaded(addin);
}
///
/// Returns whether the given is loaded.
///
///
///
public static bool IsModuleLoaded(Module module)
{
return SessionService.IsModuleLoaded(module);
}
///
/// Loads the given .
///
///
public static bool LoadAddin(Addin addin)
{
return SessionService.LoadAddin(addin);
}
///
/// Unloads the given .
///
///
public static bool UnloadAddin(Addin addin)
{
return SessionService.UnloadAddin(addin);
}
///
/// Unloads all the loaded s.
///
public static void UnloadAllAddins()
{
UnloadAllAddins(false);
}
///
/// Unloads all the loaded s. Used for tests mostly.
///
/// Whether to destroy event handlers.
public static void UnloadAllAddins(bool destroyHandlers)
{
SessionService.UnloadAllAddins(destroyHandlers);
}
///
/// This method will reevaluate all the loaded s.
///
///
/// Call this periodically in your application. The more frequent the better but
/// there's a performance cost associated with it.
///
public static void ReevaluatePolledConditionNodes()
{
SessionService.ConditionManager.ReevaluatePolledConditionNodes();
}
///
/// Gets an extension node at the given .
///
///
///
public static ExtensionNode GetExtensionNode(string path)
{
TreeNode node = ExtensionTree[path];
if (node == null)
{
return null;
}
return node.ExtensionNode;
}
///
/// Gets a list of extension nodes at the given with type .
///
///
/// This method returns only the objects of type and ignores other nodes.
///
/// Type of extension nodes.
///
/// A non null list of extension nodes of type . List may be empty if the path does not exist.
public static IEnumerable GetExtensionNodes(string path) where T : ExtensionNode
{
return m_implementation.GetExtensionNodes(path);
}
///
/// Gets a list of extension objects at a given .
///
///
/// Returns an empty collection when path does not exists.
///
///
///
///
public static IList GetExtensionObjects(string path)
{
return m_implementation.GetExtensionObjects(path);
}
///
/// Creates a new list of extension objects from the given .
///
///
/// This method returns only the objects of type and ignores other created objects.
///
///
///
///
public static IEnumerable CreateExtensionObjects(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;
}
}
///
/// Registers the given on the at the given .
///
///
///
public static void AddExtensionChangedHandler(string path, EventHandler handler)
{
SessionService.AddExtensionChangedHandler(path, handler);
}
///
/// Unregisters the given on the at the given .
///
///
///
public static void RemoveExtensionChangedHandler(string path, EventHandler handler)
{
SessionService.RemoveExtensionChangedHandler(path, handler);
}
///
/// For testing purposes, let swap the implementation.
///
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);
}
}
}