/// <summary> /// Inserts a new cache decorator at the start of the chain of decorators terminating at the /// <paramref name="decorated"/> instance supplied /// </summary> /// <param name="decorated">The existing cache to insert a new cache decorator into it's chain</param> /// <param name="createDecoration"> /// A delegate that takes the cache at the head of the chain and creates the decorator to be inserted /// </param> public virtual ICache InsertDecoratorAtStartOfChain(ICache decorated, Func <ICache, CacheDecorator> createDecoration) { var cacheDecorator = (CacheDecorator)decorated.GetDecoratorChain().LastOrDefault(); if (cacheDecorator == null) { return(createDecoration(decorated)); } // we need to insert statistics decorator as the first decorator in the chain // this means redefining the existing chain... // the reason why we need to do this is a decorator at the end of the chain can be by-passed using the // ICache.As method. // By adding the statistics cache at the start of the chain we ensure that it will always be called // find the last decorator in the chain CacheDecorator insert = createDecoration(cacheDecorator.DecoratedCache); cacheDecorator.DecoratedCache = insert; return(decorated); }
public virtual ICache InsertDecoratorBetween <TStart, TEnd>(ICache decorated, Func <ICache, CacheDecorator> createDecoration) where TEnd : class, ICache where TStart : class, ICache { List <CacheDecorator> chain = decorated.GetDecoratorChain().OfType <CacheDecorator>().ToList(); var end = chain.CacheOfType <TEnd>().LastOrDefault() as CacheDecorator; var start = chain.CacheOfType <TStart>().LastOrDefault() as CacheDecorator; if (!ReferenceEquals(end, null)) { int endPosition = chain.IndexOf(end); if (endPosition == 0) { // create a new head for the existing chain return(createDecoration(end)); } else { // insert new decorator into exising chain CacheDecorator insert = createDecoration(end); CacheDecorator beforeEnd = chain[endPosition - 1]; beforeEnd.DecoratedCache = insert; return(decorated); } } else if (!ReferenceEquals(start, null)) { CacheDecorator insert = createDecoration(start.DecoratedCache); start.DecoratedCache = insert; return(decorated); } else { // create a chain with our new decorator return(createDecoration(decorated)); } }