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

408 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using JD.Kernel.Structs;
using JD.LogService;
using JD.TeaBoxAddinSystem.Addins.Description.FileReferences;
namespace JD.TeaBoxAddinSystem.Addins.Description
{
/// <summary>
/// A module is collection of extensions, that use specific assemblies and have specific dependencies towards other addins.
/// </summary>
public sealed class Module : AddinObject
{
#region Variables
private static readonly RuntimeAssembly m_coreRuntime = new RuntimeAssembly(typeof(Module).Assembly);
private readonly AddinCollection<AddinReference> m_dependencies = new AddinCollection<AddinReference>();
private readonly AddinObjectCollection<AssemblyFileReference> m_assemblies = new AddinObjectCollection<AssemblyFileReference>();
private readonly AddinObjectCollection<ResourceFileReference> m_resourceFiles = new AddinObjectCollection<ResourceFileReference>();
private readonly AddinObjectCollection<FileReference> m_otherFiles = new AddinObjectCollection<FileReference>();
private readonly AddinObjectCollection<Extension> m_extensions = new AddinObjectCollection<Extension>();
private readonly ModuleResources m_moduleResources;
private Addin m_addin;
#endregion
#region Constructor
/// <summary>
/// Constructor.
/// </summary>
public Module()
{
Module = this;
m_moduleResources = new ModuleResources(this);
}
#endregion
#region Properties
/// <summary>
/// Assemblies used by this module.
/// </summary>
public IList<AssemblyFileReference> Assemblies
{
get
{
return m_assemblies;
}
}
/// <summary>
/// Resource files used by this module.
/// </summary>
public IList<ResourceFileReference> ResourceFiles
{
get
{
return m_resourceFiles;
}
}
/// <summary>
/// Other files used by this module.
/// </summary>
public IList<FileReference> OtherFiles
{
get
{
return m_otherFiles;
}
}
/// <summary>
/// All the files needed by this module.
/// </summary>
public IEnumerable<FileReference> AllFiles
{
get
{
foreach (FileReference reference in Assemblies)
{
yield return reference;
}
foreach (FileReference reference in ResourceFiles)
{
yield return reference;
}
foreach (FileReference reference in OtherFiles)
{
yield return reference;
}
}
}
/// <summary>
/// Dependencies of the module.
/// </summary>
public IList<AddinReference> Dependencies
{
get
{
return m_dependencies;
}
}
/// <summary>
/// All the dependencies of this module, including those of the main module.
/// </summary>
public IEnumerable<AddinReference> AllDependencies
{
get
{
foreach (AddinReference reference in Dependencies)
{
yield return reference;
}
if (Addin != null && !IsMainModule)
{
foreach (AddinReference reference in Addin.MainModule.Dependencies)
{
yield return reference;
}
}
}
}
/// <summary>
/// Extensions of the module.
/// </summary>
public IList<Extension> Extensions
{
get
{
return m_extensions;
}
}
/// <summary>
/// Resources available to this module.
/// </summary>
public IResources Resources
{
get
{
return m_moduleResources;
}
}
internal ModuleResources InternalResources
{
get
{
return m_moduleResources;
}
}
internal bool IsMainModule
{
get
{
System.Diagnostics.Debug.Assert(Addin != null, "Can only check IsMainModule if module is in addin");
return Addin.MainModule == this;
}
}
#endregion
#region Methods
/// <summary>
/// Creates an instance of the requested type. Log any creation error error.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="typename"></param>
/// <param name="succes"></param>
/// <returns></returns>
internal T TryCreateInstance<T>(string typename, out bool succes)
{
return TryCreateInstance<T>(FileLocation.GetValueOrDefault(), typename, out succes);
}
/// <summary>
/// Creates an instance of the requested type. Log any creation error error.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="fileLocation">Use this file location to log errors.</param>
/// <param name="typename"></param>
/// <param name="succes"></param>
/// <returns></returns>
internal T TryCreateInstance<T>(FileLocation fileLocation, string typename, out bool succes)
{
try
{
object value = CreateInstance(typename);
if (value == null)
{
AddinManager.Log(new Error(LogCategory.Error, "Unable to find type '{0}' in assemblies.", typename) { Origin = fileLocation });
}
else if (!(value is T))
{
AddinManager.Log(new Error(LogCategory.Error, "Unmatching type, looking for a '{0}' got a '{1}'.", typeof(T).FullName, value.GetType()) { Origin = fileLocation });
}
else
{
succes = true;
return (T)value;
}
}
catch (Exception ex)
{
AddinManager.Log(new Error(LogCategory.Error, "Error while trying to create type '{0}'. Details : {1}", typename, ex.Message) { Origin = fileLocation });
}
succes = false;
return default(T);
}
/// <summary>
/// Creates an instance of an object whose type is defined in this <see cref="Module"/> or one of its dependencies.
/// </summary>
/// <param name="typeName">The full name of the type to create.</param>
/// <param name="arguments">Arguments to be passed to the constructor of the object.</param>
/// <returns>The created object, or null if it could not be created.</returns>
public object CreateInstance(string typeName, params object[] arguments)
{
object o;
foreach (AssemblyFileReference assembly in m_assemblies)
{
o = assembly.Runtime.CreateInstance(typeName, arguments);
if (o != null)
{
return o;
}
}
// Not found, look in main module
if (Addin != null && !IsMainModule)
{
o = Addin.MainModule.CreateInstance(typeName, arguments);
if (o != null)
{
return o;
}
}
// Not found, look in dependent addins
foreach (Module dependencyModule in AddinManager.SessionService.GetLoadedDependencies(this))
{
o = dependencyModule.CreateInstance(typeName, arguments);
if (o != null)
{
return o;
}
}
// Check in this assembly
o = m_coreRuntime.CreateInstance(typeName, arguments);
if (o != null)
{
return o;
}
return null;
}
/// <summary>
/// Creates an instance of the requested type. Log any creation error error.
/// </summary>
/// <param name="typename"></param>
/// <param name="succes"></param>
/// <returns></returns>
internal Type TryGetType(string typename, out bool succes)
{
return TryGetType(FileLocation.GetValueOrDefault(), typename, out succes);
}
/// <summary>
/// Creates an instance of the requested type. Log any creation error error.
/// </summary>
/// <param name="fileLocation">Use this file location to log errors.</param>
/// <param name="typename"></param>
/// <param name="success"></param>
/// <returns></returns>
internal Type TryGetType(FileLocation fileLocation, string typename, out bool success)
{
try
{
Type type = GetType(typename);
if (type == null)
{
AddinManager.Log(new Error(LogCategory.Error, "Unable to find type '{0}' in assemblies.", typename) { Origin = fileLocation });
}
else
{
success = true;
return type;
}
}
catch (Exception ex)
{
AddinManager.Log(new Error(LogCategory.Error, "Error while obtaining type '{0}'. Details : {1}", typename, ex.Message) { Origin = fileLocation });
}
success = false;
return null;
}
/// <summary>
/// Gets a specific type within this <see cref="Module"/> or one of its dependencies.
/// </summary>
/// <param name="typeName">Full name of the type.</param>
/// <returns>A <see cref="Type"/> corresponding to the given type, or null if not found.</returns>
public Type GetType(string typeName)
{
Type type = GetTypeImpl(typeName);
if (type != null)
{
return type;
}
// Check in this assembly
type = m_coreRuntime.GetType(typeName);
if (type != null)
{
return type;
}
return string.IsNullOrEmpty(typeName) ? null : Type.GetType(typeName, false, true);
}
private Type GetTypeImpl(string typeName)
{
Type type;
foreach (AssemblyFileReference assembly in m_assemblies)
{
type = assembly.Runtime.GetType(typeName);
if (type != null)
{
return type;
}
}
// Not found, look in main module
if (Addin != null && !IsMainModule)
{
type = Addin.MainModule.GetType(typeName);
if (type != null)
{
return type;
}
}
// Not found, look in dependent addins
foreach (Module dependencyModule in AddinManager.SessionService.GetLoadedDependencies(this))
{
type = dependencyModule.GetTypeImpl(typeName);
if (type != null)
{
return type;
}
}
return null;
}
/// <summary>
/// Overriden.
/// </summary>
/// <returns></returns>
internal override Addin GetAddin()
{
return m_addin;
}
internal void SetAddin(Addin addin)
{
m_addin = addin;
}
/// <summary>
/// Overriden.
/// </summary>
/// <param name="e"></param>
internal override void OnModuleChanged(EventArgs e)
{
m_assemblies.Owner = this;
m_resourceFiles.Owner = this;
m_otherFiles.Owner = this;
m_dependencies.Owner = this;
m_extensions.Owner = this;
base.OnModuleChanged(e);
}
#endregion
}
}