⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scriptobjectbuilder.cs

📁 AJAX 应用 实现页面的无刷新
💻 CS
📖 第 1 页 / 共 3 页
字号:
                    // since we're inside the lock, check again just in case.
                    //
                    if (ignoreStartingTypeReferences || !_cache.TryGetValue(type, out entries))
                    {
                        entries = new List<ResourceEntry>();

                        // Get the required scripts by type
                        List<RequiredScriptAttribute> requiredScripts = new List<RequiredScriptAttribute>();
                        foreach (RequiredScriptAttribute attr in type.GetCustomAttributes(typeof(RequiredScriptAttribute), true))
                        {
                            requiredScripts.Add(attr);
                        }
                        
                        requiredScripts.Sort(delegate(RequiredScriptAttribute left, RequiredScriptAttribute right) { return left.LoadOrder.CompareTo(right.LoadOrder); });
                        foreach (RequiredScriptAttribute attr in requiredScripts)
                        {
                            if (attr.ExtenderType != null)
                            {
                                // extrapolate dependent references and add them to the ref list.
                                entries.AddRange(GetScriptReferencesInternal(attr.ExtenderType, typeReferenceStack, false));
                            }
                        }

                        // Get the client script resource values for this type
                        int order = 0;

                        // create a new list so we can sort it independently.
                        //
                        List<ResourceEntry> newEntries = new List<ResourceEntry>();
                        for (Type current = type; current != null && current != typeof(object); current = current.BaseType)
                        {
                            if (ignoreStartingTypeReferences && (current == type))
                            {
                                // Skip the starting type because ScriptPath is being used to override
                                continue;
                            }

                            object[] attrs = Attribute.GetCustomAttributes(current, typeof(ClientScriptResourceAttribute), false);
                            order -= attrs.Length;

                            foreach (ClientScriptResourceAttribute attr in attrs)
                            {
                                ResourceEntry re = new ResourceEntry(attr.ResourcePath, current, order + attr.LoadOrder);

                                // check for dups in the list.
                                //
                                if (!entries.Contains(re) && !newEntries.Contains(re))
                                {
                                    newEntries.Add(re);
                                }
                            }
                        }

                        // sort the list and add it to the array.
                        //
                        newEntries.Sort(delegate(ResourceEntry l, ResourceEntry r) { return l.Order.CompareTo(r.Order); });
                        entries.AddRange(newEntries);

                        // Cache the reference list and return (but don't cache if this response is unusual for some reason)
                        //
                        if (!ignoreStartingTypeReferences)
                        {
                            _cache.Add(type, entries);
                        }
                    }

                    return entries;
                }
            }
            finally
            {
                // Remove the type as further requests will get the cached reference
                typeReferenceStack.Pop();
            }
        }

        /// <summary>
        /// Gets the css references for a type and walks the type's dependencies with circular-reference checking
        /// </summary>
        /// <param name="type"></param>
        /// <param name="typeReferenceStack"></param>
        /// <returns></returns>
        private static IEnumerable<string> GetCssReferences(Control control, Type type, Stack<Type> typeReferenceStack)
        {
            // Verify no circular references
            if (typeReferenceStack.Contains(type))
            {
                throw new InvalidOperationException("Circular reference detected.");
            }

            // Look for a cached set of references
            IList<string> references;
            if (_cssCache.TryGetValue(type, out references))
            {
                return references;
            }

            // Track this type to prevent circular references
            typeReferenceStack.Push(type);
            try
            {
                lock (_sync)
                {
                    // double-checked lock
                    if (_cssCache.TryGetValue(type, out references))
                    {
                        return references;
                    }

                    // build the reference list
                    List<string> referenceList = new List<string>();

                    // Get the required scripts by type
                    List<RequiredScriptAttribute> requiredScripts = new List<RequiredScriptAttribute>();
                    foreach (RequiredScriptAttribute attr in type.GetCustomAttributes(typeof(RequiredScriptAttribute), true))
                    {
                        requiredScripts.Add(attr);
                    }
                    requiredScripts.Sort(delegate(RequiredScriptAttribute left, RequiredScriptAttribute right) { return left.LoadOrder.CompareTo(right.LoadOrder); });
                    foreach (RequiredScriptAttribute attr in requiredScripts)
                    {
                        if (attr.ExtenderType != null)
                        {
                            // extrapolate dependent references
                            referenceList.AddRange(GetCssReferences(control, attr.ExtenderType, typeReferenceStack));
                        }
                    }

                    // Get the client script resource values for this type
                    List<ResourceEntry> entries = new List<ResourceEntry>();
                    int order = 0;
                    for (Type current = type; current != null && current != typeof(object); current = current.BaseType)
                    {
                        object[] attrs = Attribute.GetCustomAttributes(current, typeof(ClientCssResourceAttribute), false);
                        order -= attrs.Length;

                        foreach (ClientCssResourceAttribute attr in attrs)
                        {
                            entries.Add(new ResourceEntry(attr.ResourcePath, current, order + attr.LoadOrder));
                        }
                    }
                    entries.Sort(delegate(ResourceEntry l, ResourceEntry r) { return l.Order.CompareTo(r.Order); });
                    foreach (ResourceEntry entry in entries)
                    {
                        referenceList.Add(control.Page.ClientScript.GetWebResourceUrl(entry.ComponentType, entry.ResourcePath));
                    }

                    // Remove duplicates from reference list
                    Dictionary<string, object> cookies = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
                    List<string> newReferenceList = new List<string>();
                    foreach (string refr in referenceList)
                    {
                        if (cookies.ContainsKey(refr))
                            continue;
                        cookies.Add(refr, null);
                        newReferenceList.Add(refr);
                    }

                    // Create a readonly dictionary to hold the values
                    references = new ReadOnlyCollection<string>(newReferenceList);

                    // Cache the reference
                    _cssCache.Add(type, references);

                    // return the list
                    return references;
                }
            }
            finally
            {
                // Remove the type as further requests will get the cached reference
                typeReferenceStack.Pop();
            }
        }

        private struct ResourceEntry
        {
            public string ResourcePath;
            public Type ComponentType;
            public int Order;

            private string AssemblyName
            {
                get 
                {
                    return ComponentType == null ? "" : ComponentType.Assembly.FullName;
                }
            }

            public ResourceEntry(string path, Type componentType, int order)
            {
                ResourcePath = path;
                ComponentType = componentType;
                Order = order;
            }

            public ScriptReference ToScriptReference()
            {
                ScriptReference refr = new ScriptReference();
                refr.Assembly = AssemblyName;
                refr.Name = ResourcePath;
                return refr;
            }

            public override bool Equals(object obj)
            {
                ResourceEntry other = (ResourceEntry)obj;
                return ResourcePath.Equals(other.ResourcePath, StringComparison.OrdinalIgnoreCase)
                       && AssemblyName.Equals(other.AssemblyName, StringComparison.OrdinalIgnoreCase);
            }

            public static bool operator ==(ResourceEntry obj1, ResourceEntry obj2)
            {
                return obj1.Equals(obj2);
            }

            public static bool operator !=(ResourceEntry obj1, ResourceEntry obj2)
            {
                return !obj1.Equals(obj2);
            }

            public override int GetHashCode()
            {
                return AssemblyName.GetHashCode() ^ ResourcePath.GetHashCode();
            }
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -