using System; using System.Collections.Generic; using System.Threading; namespace Umbraco.Core.Resolving { /// /// A Resolver which manages an ordered list of objects. /// /// The type of the resolver. /// The type of the resolved objects. /// /// Used to resolve multiple types from a collection. The collection can also be modified at runtime/application startup. /// An example of this is MVCs ViewEngines collection. /// internal abstract class ManyObjectResolverBase : ResolverBase where TResolver : class where TResolved : class { readonly List _resolved; protected readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim(); /// /// Initializes a new instance of the class with an empty list of objects. /// protected ManyObjectResolverBase() { _resolved = new List(); } /// /// Initializes a new instance of the class with an initial list of objects. /// /// The list of objects. protected ManyObjectResolverBase(IEnumerable value) { _resolved = new List(value); } /// /// Gets the list of objects. /// protected IEnumerable Values { get { return _resolved; } } /// /// Removes an object. /// /// The object to remove. public void Remove(TResolved value) { Resolution.EnsureNotFrozen(); using (new WriteLock(Lock)) { _resolved.Remove(value); } } /// /// Adds an object to the end of the list. /// /// The object to be added. public void Add(TResolved value) { Resolution.EnsureNotFrozen(); using (var l = new UpgradeableReadLock(Lock)) { if (_resolved.Contains(value)) { throw new InvalidOperationException("The object " + value + " already exists in the collection"); }; l.UpgradeToWriteLock(); _resolved.Add(value); } } /// /// Clears the list. /// public void Clear() { Resolution.EnsureNotFrozen(); using (new WriteLock(Lock)) { _resolved.Clear(); } } /// /// Inserts an object at the specified index. /// /// The zero-based index at which the object should be inserted. /// The object to insert. public void Insert(int index, TResolved value) { Resolution.EnsureNotFrozen(); using (var l = new UpgradeableReadLock(Lock)) { if (_resolved.Contains(value)) { throw new InvalidOperationException("The object " + value + " already exists in the collection"); }; l.UpgradeToWriteLock(); _resolved.Insert(index, value); } } } }