408 lines
12 KiB
C#
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
|
|
}
|
|
}
|