Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            ResourceEntry other = (ResourceEntry)obj;

            return(String.Compare(RefKey, other.RefKey, true, CultureInfo.CurrentCulture) == 0);
        }
Пример #2
0
        /// <summary>
        /// Gets the script 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 List <ResourceEntry> GetScriptReferencesInternal(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 outside of the lock for perf.
            //
            List <ResourceEntry> entries;

            if (_cache.TryGetValue(type, out entries))
            {
                return(entries);
            }

            // Track this type to prevent circular references
            typeReferenceStack.Push(type);
            try
            {
                lock (_sync)
                {
                    // since we're inside the lock, check again just in case.
                    //
                    if (!_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 dependant references and add them to the ref list.
                                entries.AddRange(GetScriptReferencesInternal(attr.ExtenderType, typeReferenceStack));
                            }
                        }

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

                        // create a new list so we can sort it independantly.
                        //
                        List <ResourceEntry> newEntries = new List <ResourceEntry>();
                        for (Type current = type; current != null && current != typeof(object); current = current.BaseType)
                        {
                            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, attr.Cacheability);

                                // 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
                        //
                        _cache.Add(type, entries);
                    }

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