using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using Umbraco.Core.Resolving; using umbraco.interfaces; namespace Umbraco.Core { internal sealed class CacheRefreshersResolver : ManyObjectResolverBase { #region Singleton private static readonly CacheRefreshersResolver Instance = new CacheRefreshersResolver(PluginTypeResolver.Current.ResolveCacheRefreshers()); public static CacheRefreshersResolver Current { get { return Instance; } } #endregion #region Constructors static CacheRefreshersResolver() { } /// /// Constructor /// /// /// /// We are creating Transient instances (new instances each time) because this is how the legacy code worked and /// I don't want to muck anything up by changing them to application based instances. /// TODO: However, it would make much more sense to do this and would speed up the application plus this would make the GetById method much easier. /// internal CacheRefreshersResolver(IEnumerable refreshers) : base(true) { foreach (var l in refreshers) { this.Add(l); } } #endregion /// /// Maintains a list of Ids and their types when first call to CacheResolvers or GetById occurs, this is used /// in order to return a single object by id without instantiating the entire type stack. /// private static ConcurrentDictionary _refreshers; private readonly ReaderWriterLockSlim _lock= new ReaderWriterLockSlim(); /// /// Gets the implementations. /// public IEnumerable CacheResolvers { get { EnsureRefreshersList(); return Values; } } /// /// Returns a new ICacheRefresher instance by id /// /// /// public ICacheRefresher GetById(Guid id) { EnsureRefreshersList(); return !_refreshers.ContainsKey(id) ? null : PluginTypeResolver.Current.CreateInstance(_refreshers[id]); } /// /// Populates the refreshers dictionary to allow us to instantiate a type by Id since the ICacheRefresher type doesn't contain any metadata /// private void EnsureRefreshersList() { using (var l = new UpgradeableReadLock(_lock)) { if (_refreshers == null) { l.UpgradeToWriteLock(); _refreshers = new ConcurrentDictionary(); foreach(var v in Values) { _refreshers.TryAdd(v.UniqueIdentifier, v.GetType()); } } } } } }