Kentico中的ModuleEntryManager
Kentico\Core\Modules\Entries\ModuleEntryManager.cs
/// <summary> /// Pre-initializes modules. /// </summary> /// <remarks> /// PreInit applies to all modules. Even to those which are not installed. /// </remarks> internal static void PreInit() { ModuleCollectionsInitialization(); TypeManager.PreInitializeTypes(); var modules = Modules.Where(x => x.Module != null).Select(x => x.Module); foreach (var module in modules) { module.PreInit(); } }
/// <summary> /// Initialize the collections of modules /// </summary> private static void ModuleCollectionsInitialization() { if (!mModuleCollectionsInitialized) { lock (mModulesLock) { if (!mModuleCollectionsInitialized) { // Prepare both collections var modules = GetDiscoverableModules().ToList(); var moduleLookup = modules.ToDictionary(x => x.Name, StringComparer.InvariantCultureIgnoreCase); var moduleItems = new ModuleCollections(moduleLookup, modules); Thread.MemoryBarrier(); // Publish them atomically mModuleCollections = moduleItems; mModuleCollectionsInitialized = true; } } } }
/// <summary> /// Returns an enumerable collection of discoverable modules sorted by module dependencies. /// </summary> /// <returns>An enumerable collection of discoverable modules sorted by module dependencies.</returns> private static IEnumerable<ModuleInfo> GetDiscoverableModules() { var entries = new ModuleDiscovery().GetModules().ToList(); return new ModuleEntrySort().Sort(entries).Select(x => new ModuleInfo(x)); }
/// <summary> /// Returns an enumerable collection of application modules. /// </summary> /// <remarks> /// The discovery process looks for modules in discoverable assemblies (see <see cref="CMS.Core.AssemblyDiscoveryHelper"/> for more information). /// The module type is located using the <see cref="RegisterModuleAttribute"/>. /// </remarks> /// <returns>An enumerable collection of application modules.</returns> public IEnumerable<ModuleEntry> GetModules() { var modules = new List<ModuleEntry>(); var assemblies = AssemblyDiscoveryHelper.GetAssemblies(discoverableOnly: true); foreach (var assembly in assemblies) { modules.AddRange(GetModules(assembly)); } return modules; }
/// <summary> /// Returns an enumerable collection of application assemblies. /// </summary> /// <param name="discoverableOnly">A value indicating whether the discovery process will locate only assemblies decorated with the <see cref="CMS.AssemblyDiscoverableAttribute"/> attribute.</param> /// <remarks> /// The discovery process looks for assemblies in the directories that the assembly resolver probes. /// By default, all the application assemblies are returned, but there are exceptions. /// <list type="number"> /// <item><description>If the <paramref name="discoverableOnly"/> is set to <c>true</c>, assemblies without the <see cref="CMS.AssemblyDiscoverableAttribute"/> attribute are excluded from discovery.</description></item> /// <item><description>If there is a file with the "exclude" extension, for example MyCustomAssembly.dll.exclude, the MyCustomAssembly.dll is excluded from discovery.</description></item> /// <item><description>Assemblies from the GAC are always excluded from discovery.</description></item> /// </list> /// </remarks> /// <returns>An enumerable collection of application assemblies.</returns> public static IEnumerable<Assembly> GetAssemblies(bool discoverableOnly) { return AssemblyDiscovery.GetAssemblies(discoverableOnly) .Union(mAdditionalAssemblies, new AssemblyFullNameComparer()); }
public IEnumerable<Assembly> GetAssemblies(bool discoverableOnly) { return discoverableOnly ? DiscoverableAssemblies : Assemblies; }
/// <summary> /// A list of discoverable application assemblies. /// </summary> protected ICollection<Assembly> DiscoverableAssemblies { get { return mDiscoverableAssemblies ?? (mDiscoverableAssemblies = ExecuteGetAssemblies(true)); } }
/// <summary> /// Returns a read-only collection of application assemblies matching the specified criteria. /// </summary> /// <param name="onlyDiscoverable">A value indicating whether the discovery process will locate only assemblies decorated with the <see cref="CMS.AssemblyDiscoverableAttribute"/> attribute.</param> /// <returns>A read-only collection of application assemblies matching the specified criteria.</returns> private ICollection<Assembly> ExecuteGetAssemblies(bool onlyDiscoverable) { var assemblies = new List<Assembly>(); var preloadedAssemblies = AppDomain .CurrentDomain .GetAssemblies() .GroupBy(assembly => assembly.FullName) .ToDictionary(x => x.Key, x => x.First()); // Process all found assemblies var filePaths = GetAssembliesFilePaths(); foreach (var filePath in filePaths) { if (IsExcluded(filePath)) { continue; } try { var assemblyName = AssemblyName.GetAssemblyName(filePath); if (IsExcluded(assemblyName)) { continue; } if (onlyDiscoverable) { AddOnlyDiscoverableAssembly(assemblies, preloadedAssemblies, assemblyName, filePath); } else { AddAssembly(assemblies, assemblyName); } } catch (BadImageFormatException) { // Ignore error caused by load of native assembly } catch (Exception exception) { OnGetAssemblyFailed(filePath, exception); // OnGetAssemblyFailed overrides may throw another (wrapped) exception, otherwise throw this one throw; } } assemblies.Sort((a, b) => StringComparer.InvariantCultureIgnoreCase.Compare(a.FullName, b.FullName)); return assemblies.AsReadOnly(); }
/// <summary> /// If and only if the assembly (specified by <paramref name="assemblyName"/> and <paramref name="filePath"/>) is discoverable, /// method loads the assembly and adds it into the <paramref name="assemblies"/> collection. /// </summary> /// <seealso cref="IsAssemblyDiscoverable(string)"/> /// <seealso cref="IsAssemblyDiscoverable(Assembly)"/> private void AddOnlyDiscoverableAssembly(ICollection<Assembly> assemblies, Dictionary<string, Assembly> preloadedAssemblies, AssemblyName assemblyName, string filePath) { Assembly assembly; if (preloadedAssemblies.TryGetValue(assemblyName.FullName, out assembly)) { if (IsAssemblyDiscoverable(assembly)) { assemblies.Add(assembly); } } else if (IsAssemblyDiscoverable(filePath)) { AddAssembly(assemblies, assemblyName); } }
/// <summary> /// Returns true if the given assembly is discoverable. /// </summary> /// <param name="assembly">Assembly in question</param> private bool IsAssemblyDiscoverable(Assembly assembly) { return assembly .GetCustomAttributesData() .Any(customAttribute => (customAttribute.Constructor.DeclaringType != null) && (customAttribute.Constructor.DeclaringType.FullName == ASSEMBLY_DISCOVERABLE_ATTRIBUTE_FULLNAME)); }
/// <summary> /// The full name of the AssemblyDiscoverableAttribute class. /// </summary> private const string ASSEMBLY_DISCOVERABLE_ATTRIBUTE_FULLNAME = "CMS.AssemblyDiscoverableAttribute";
遇到如下错误:
[MissingMethodException: No parameterless constructor defined for this object.] System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0 System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +142 System.Activator.CreateInstance(Type type, Boolean nonPublic) +107 System.Activator.CreateInstance(Type type) +13 CMS.Core.<>c__DisplayClass1_0.<GetModules>b__0(RegisterModuleAttribute attribute) +18 System.Linq.WhereSelectArrayIterator`2.MoveNext() +145 System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection) +464 CMS.Core.ModuleDiscovery.GetModules() +202 CMS.Core.ModuleEntryManager.GetDiscoverableModules() +29 CMS.Core.ModuleEntryManager.ModuleCollectionsInitialization() +122 CMS.Core.ModuleEntryManager.PreInit() +21 CMS.Core.AppCore.PreInit() +113 CMS.DataEngine.CMSApplication.PreInit() +119 CMS.DataEngine.CMSHttpApplication.InitApplication(Assembly webProjectAssembly) +65