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

 

posted @ 2021-07-28 15:39  ChuckLu  阅读(46)  评论(0编辑  收藏  举报