Beispiel #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);
        }
		/// <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();
			}
		}
Beispiel #3
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();
            }
        }