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