public static LOGI.Framework.Toolkit.OpenSource.AspectF.AspectF CacheList <TItemType, TListType>(this LOGI.Framework.Toolkit.OpenSource.AspectF.AspectF aspect,
                                                                                                         ICacheWrapper cacheResolver, string listCacheKey, Func <TItemType, string> getItemKey)
            where TListType : IList <TItemType>, new()
        {
            return(aspect.Combine(work =>
            {
                var workDelegate = aspect.WorkDelegate as Func <TListType>;

                // Replace the actual work delegate with a new delegate so that
                // when the actual work delegate returns a collection, each item
                // in the collection is stored in cache individually.
                Func <TListType> newWorkDelegate = () =>
                {
                    if (workDelegate != null)
                    {
                        TListType collection = workDelegate();
                        foreach (TItemType item in collection)
                        {
                            string key = getItemKey(item);
                            cacheResolver.Save(key, item);
                        }
                        return collection;
                    }
                    return default(TListType);
                };
                aspect.WorkDelegate = newWorkDelegate;

                // Get the collection from cache or real source. If collection is returned
                // from cache, resolve each item in the collection from cache
                Cache <TListType>(aspect, cacheResolver, listCacheKey, work,
                                  cached =>
                {
                    // Get each item from cache. If any of the item is not in cache
                    // then discard the whole collection from cache and reload the
                    // collection from source.
                    var itemList = new TListType();
                    foreach (TItemType cachedItem in cached.Select(item => cacheResolver.Get <TItemType>(getItemKey(item))))
                    {
                        if (null != cachedItem)
                        {
                            itemList.Add(cachedItem);
                        }
                        else
                        {
                            // One of the item is missing from cache. So, discard the
                            // cached list.
                            return default(TListType);
                        }
                    }

                    return itemList;
                });
            }));
        }
        private static void GetListFromSource <TReturnType>(LOGI.Framework.Toolkit.OpenSource.AspectF.AspectF aspect, ICacheWrapper cacheResolver,
                                                            string key)
        {
            var workDelegate = aspect.WorkDelegate as Func <TReturnType>;

            if (workDelegate != null)
            {
                TReturnType realObject = workDelegate();
                cacheResolver.Save(key, realObject);
                workDelegate = () => realObject;
            }
            aspect.WorkDelegate = workDelegate;
        }