using System;
using System.Collections.Generic;
using JD.Kernel.Structs;
using JD.LogService;
using JD.TeaBoxAddinSystem.Addins.Description.FileReferences;
namespace JD.TeaBoxAddinSystem.Addins.Description
{
///
/// A module is collection of extensions, that use specific assemblies and have specific dependencies towards other addins.
///
public sealed class Module : AddinObject
{
#region Variables
private static readonly RuntimeAssembly m_coreRuntime = new RuntimeAssembly(typeof(Module).Assembly);
private readonly AddinCollection m_dependencies = new AddinCollection();
private readonly AddinObjectCollection m_assemblies = new AddinObjectCollection();
private readonly AddinObjectCollection m_resourceFiles = new AddinObjectCollection();
private readonly AddinObjectCollection m_otherFiles = new AddinObjectCollection();
private readonly AddinObjectCollection m_extensions = new AddinObjectCollection();
private readonly ModuleResources m_moduleResources;
private Addin m_addin;
#endregion
#region Constructor
///
/// Constructor.
///
public Module()
{
Module = this;
m_moduleResources = new ModuleResources(this);
}
#endregion
#region Properties
///
/// Assemblies used by this module.
///
public IList Assemblies
{
get
{
return m_assemblies;
}
}
///
/// Resource files used by this module.
///
public IList ResourceFiles
{
get
{
return m_resourceFiles;
}
}
///
/// Other files used by this module.
///
public IList OtherFiles
{
get
{
return m_otherFiles;
}
}
///
/// All the files needed by this module.
///
public IEnumerable 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;
}
}
}
///
/// Dependencies of the module.
///
public IList Dependencies
{
get
{
return m_dependencies;
}
}
///
/// All the dependencies of this module, including those of the main module.
///
public IEnumerable AllDependencies
{
get
{
foreach (AddinReference reference in Dependencies)
{
yield return reference;
}
if (Addin != null && !IsMainModule)
{
foreach (AddinReference reference in Addin.MainModule.Dependencies)
{
yield return reference;
}
}
}
}
///
/// Extensions of the module.
///
public IList Extensions
{
get
{
return m_extensions;
}
}
///
/// Resources available to this module.
///
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
///
/// Creates an instance of the requested type. Log any creation error error.
///
///
///
///
///
internal T TryCreateInstance(string typename, out bool succes)
{
return TryCreateInstance(FileLocation.GetValueOrDefault(), typename, out succes);
}
///
/// Creates an instance of the requested type. Log any creation error error.
///
///
/// Use this file location to log errors.
///
///
///
internal T TryCreateInstance(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);
}
///
/// Creates an instance of an object whose type is defined in this or one of its dependencies.
///
/// The full name of the type to create.
/// Arguments to be passed to the constructor of the object.
/// The created object, or null if it could not be created.
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;
}
///
/// Creates an instance of the requested type. Log any creation error error.
///
///
///
///
internal Type TryGetType(string typename, out bool succes)
{
return TryGetType(FileLocation.GetValueOrDefault(), typename, out succes);
}
///
/// Creates an instance of the requested type. Log any creation error error.
///
/// Use this file location to log errors.
///
///
///
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;
}
///
/// Gets a specific type within this or one of its dependencies.
///
/// Full name of the type.
/// A corresponding to the given type, or null if not found.
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;
}
///
/// Overriden.
///
///
internal override Addin GetAddin()
{
return m_addin;
}
internal void SetAddin(Addin addin)
{
m_addin = addin;
}
///
/// Overriden.
///
///
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
}
}