using System; using System.Collections.Generic; using System.Linq; namespace Umbraco.Core.Composing { /// /// Implements a weighted collection builder. /// /// The type of the builder. /// The type of the collection. /// The type of the items. public abstract class WeightedCollectionBuilderBase : CollectionBuilderBase where TBuilder : WeightedCollectionBuilderBase where TCollection : class, IBuilderCollection { protected abstract TBuilder This { get; } /// /// Clears all types in the collection. /// /// The builder. public TBuilder Clear() { Configure(types => types.Clear()); return This; } /// /// Adds a type to the collection. /// /// The type to add. /// The builder. public TBuilder Add() where T : TItem { Configure(types => { var type = typeof(T); if (types.Contains(type) == false) types.Add(type); }); return This; } /// /// Adds a type to the collection. /// /// The type to add. /// The builder. public TBuilder Add(Type type) { Configure(types => { EnsureType(type, "register"); if (types.Contains(type) == false) types.Add(type); }); return This; } /// /// Adds types to the collection. /// /// The types to add. /// The builder. public TBuilder Add(IEnumerable types) { Configure(list => { foreach (var type in types) { // would be detected by CollectionBuilderBase when registering, anyways, but let's fail fast EnsureType(type, "register"); if (list.Contains(type) == false) list.Add(type); } }); return This; } /// /// Removes a type from the collection. /// /// The type to remove. /// The builder. public TBuilder Remove() where T : TItem { Configure(types => { var type = typeof(T); if (types.Contains(type)) types.Remove(type); }); return This; } /// /// Removes a type from the collection. /// /// The type to remove. /// The builder. public TBuilder Remove(Type type) { Configure(types => { EnsureType(type, "remove"); if (types.Contains(type)) types.Remove(type); }); return This; } protected override IEnumerable GetRegisteringTypes(IEnumerable types) { var list = types.ToList(); list.Sort((t1, t2) => GetWeight(t1).CompareTo(GetWeight(t2))); return list; } public virtual int DefaultWeight { get; set; } = 100; protected virtual int GetWeight(Type type) { var attr = type.GetCustomAttributes(typeof(WeightAttribute), false).OfType().SingleOrDefault(); return attr?.Weight ?? DefaultWeight; } } }