Example #1
0
        public void UpdateCacheContext_PrefersAbsoluteExpirationSpecifiedOnEntryLinkOverExpiresOn()
        {
            // Arrange
            var expiresOn1   = DateTimeOffset.UtcNow.AddDays(12);
            var expiresOn2   = DateTimeOffset.UtcNow.AddMinutes(4);
            var cache        = new MemoryCache(new MemoryCacheOptions());
            var cacheContext = new Mock <ICacheSetContext>();
            var sequence     = new MockSequence();

            cacheContext.InSequence(sequence)
            .Setup(c => c.SetAbsoluteExpiration(expiresOn1))
            .Verifiable();

            cacheContext.InSequence(sequence)
            .Setup(c => c.SetAbsoluteExpiration(expiresOn2))
            .Verifiable();

            var cacheTagHelper = new CacheTagHelper
            {
                MemoryCache = cache,
                ExpiresOn   = expiresOn1
            };

            var entryLink = new EntryLink();

            entryLink.SetAbsoluteExpiration(expiresOn2);

            // Act
            cacheTagHelper.UpdateCacheContext(cacheContext.Object, entryLink);

            // Assert
            cacheContext.Verify();
        }
Example #2
0
        public void GetWithLinkPopulatesTriggers()
        {
            var    cache = CreateCache();
            var    obj   = new object();
            string key   = "myKey";
            string key1  = "myKey1";

            var link = new EntryLink();

            var trigger = new TestTrigger()
            {
                ActiveExpirationCallbacks = true
            };

            cache.Set(key, link, context =>
            {
                context.AddExpirationTrigger(trigger);
                return(obj);
            });

            Assert.Equal(1, link.Triggers.Count());
            Assert.Null(link.AbsoluteExpiration);

            cache.Set(key1, context =>
            {
                context.AddEntryLink(link);
                return(obj);
            });
        }
Example #3
0
        public void GetWithLinkPopulatesAbsoluteExpiration()
        {
            var    cache = CreateCache();
            var    obj   = new object();
            string key   = "myKey";
            string key1  = "myKey1";

            var link = new EntryLink();

            var trigger = new TestTrigger()
            {
                ActiveExpirationCallbacks = true
            };
            var time = new DateTimeOffset(2051, 1, 1, 1, 1, 1, TimeSpan.Zero);

            cache.Set(key, link, context =>
            {
                context.SetAbsoluteExpiration(time);
                return(obj);
            });

            Assert.Equal(0, link.Triggers.Count());
            Assert.NotNull(link.AbsoluteExpiration);
            Assert.Equal(time, link.AbsoluteExpiration);

            cache.Set(key1, context =>
            {
                context.AddEntryLink(link);
                return(obj);
            });
        }
Example #4
0
        /// <inheritdoc />
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            var    key = GenerateKey(context);
            string result;

            if (!MemoryCache.TryGetValue(key, out result))
            {
                // Create an EntryLink and flow it so that it is accessible via the ambient EntryLinkHelpers.ContentLink
                // for user code.
                var entryLink = new EntryLink();
                using (entryLink.FlowContext())
                {
                    result = await context.GetChildContentAsync();
                }

                MemoryCache.Set(key, cacheSetContext =>
                {
                    UpdateCacheContext(cacheSetContext, entryLink);
                    return(result);
                });
            }

            // Clear the contents of the "cache" element since we don't want to render it.
            output.SuppressOutput();

            output.Content = result;
        }
Example #5
0
        public void UpdateCacheContext_CopiesTriggersFromEntryLink()
        {
            // Arrange
            var expiresSliding = TimeSpan.FromSeconds(30);
            var expected       = new[] { Mock.Of <IExpirationTrigger>(), Mock.Of <IExpirationTrigger>() };
            var triggers       = new List <IExpirationTrigger>();
            var cache          = new MemoryCache(new MemoryCacheOptions());
            var cacheContext   = new Mock <ICacheSetContext>();

            cacheContext.Setup(c => c.SetSlidingExpiration(expiresSliding))
            .Verifiable();
            cacheContext.Setup(c => c.AddExpirationTrigger(It.IsAny <IExpirationTrigger>()))
            .Callback <IExpirationTrigger>(triggers.Add)
            .Verifiable();
            var cacheTagHelper = new CacheTagHelper
            {
                MemoryCache    = cache,
                ExpiresSliding = expiresSliding
            };

            var entryLink = new EntryLink();

            entryLink.AddExpirationTriggers(expected);

            // Act
            cacheTagHelper.UpdateCacheContext(cacheContext.Object, entryLink);

            // Assert
            cacheContext.Verify();
            Assert.Equal(expected, triggers);
        }
Example #6
0
 Label this[string k] {
     get {
         if (!EntryLink.ContainsKey(k))
         {
             return(null);
         }
         return(EntryLink[k]);
     }
 }
Example #7
0
        public void LinkContextsCanNest()
        {
            var    cache = CreateCache();
            var    obj   = new object();
            string key   = "myKey";
            string key1  = "myKey1";

            var link1 = new EntryLink();
            var link2 = new EntryLink();

            Assert.Null(EntryLinkHelpers.ContextLink);

            using (link1.FlowContext())
            {
                Assert.StrictEqual(link1, EntryLinkHelpers.ContextLink);

                using (link2.FlowContext())
                {
                    Assert.StrictEqual(link2, EntryLinkHelpers.ContextLink);

                    var trigger = new TestTrigger()
                    {
                        ActiveExpirationCallbacks = true
                    };
                    cache.Set(key, context =>
                    {
                        context.AddExpirationTrigger(trigger);
                        return(obj);
                    });
                }

                Assert.StrictEqual(link1, EntryLinkHelpers.ContextLink);
            }

            Assert.Null(EntryLinkHelpers.ContextLink);

            Assert.Equal(0, link1.Triggers.Count());
            Assert.Null(link1.AbsoluteExpiration);
            Assert.Equal(1, link2.Triggers.Count());
            Assert.Null(link2.AbsoluteExpiration);

            cache.Set(key1, context =>
            {
                context.AddEntryLink(link2);
                return(obj);
            });
        }
        public void UpdateCacheEntryOptions_UsesAbsoluteExpirationSpecifiedOnEntryLink()
        {
            // Arrange
            var expiresOn      = DateTimeOffset.UtcNow.AddMinutes(7);
            var cache          = new MemoryCache(new MemoryCacheOptions());
            var cacheTagHelper = new CacheTagHelper(cache)
            {
            };

            var entryLink = new EntryLink();

            entryLink.SetAbsoluteExpiration(expiresOn);

            // Act
            var cacheEntryOptions = cacheTagHelper.GetMemoryCacheEntryOptions(entryLink);

            // Assert
            Assert.Equal(expiresOn, cacheEntryOptions.AbsoluteExpiration);
        }
        public void UpdateCacheEntryOptions_CopiesTriggersFromEntryLink()
        {
            // Arrange
            var expiresSliding = TimeSpan.FromSeconds(30);
            var expected       = new[] { Mock.Of <IExpirationTrigger>(), Mock.Of <IExpirationTrigger>() };
            var cache          = new MemoryCache(new MemoryCacheOptions());
            var cacheTagHelper = new CacheTagHelper(cache)
            {
                ExpiresSliding = expiresSliding
            };

            var entryLink = new EntryLink();

            entryLink.AddExpirationTriggers(expected);

            // Act
            var cacheEntryOptions = cacheTagHelper.GetMemoryCacheEntryOptions(entryLink);

            // Assert
            Assert.Equal(expected, cacheEntryOptions.Triggers.ToArray());
        }
        public void UpdateCacheEntryOptions_PrefersAbsoluteExpirationSpecifiedOnEntryLinkOverExpiresOn()
        {
            // Arrange
            var expiresOn1     = DateTimeOffset.UtcNow.AddDays(12);
            var expiresOn2     = DateTimeOffset.UtcNow.AddMinutes(4);
            var cache          = new MemoryCache(new MemoryCacheOptions());
            var cacheTagHelper = new CacheTagHelper(cache)
            {
                ExpiresOn = expiresOn1
            };

            var entryLink = new EntryLink();

            entryLink.SetAbsoluteExpiration(expiresOn2);

            // Act
            var cacheEntryOptions = cacheTagHelper.GetMemoryCacheEntryOptions(entryLink);

            // Assert
            Assert.Equal(expiresOn2, cacheEntryOptions.AbsoluteExpiration);
        }
Example #11
0
        public static void WriteEntryLink(this XmlWriter writer, EntryLink entry)
        {
            if (entry != null)
            {
                if (!string.IsNullOrWhiteSpace(entry.Href) ||
                    entry.ReadOnly__.HasValue ||
                    !string.IsNullOrWhiteSpace(entry.Rel) ||
                    entry.Entry != null)
                {
                    gdWriteStartElement(writer, "entry");

                    gdWriteAttributeString(writer, "href", entry.Href);

                    gdWriteAttributeString(writer, "readOnly", entry.ReadOnly__.Value.ToString());

                    gdWriteAttributeString(writer, "rel", entry.Rel);

                    writer.WriteContactEntry(entry.Entry);

                    writer.WriteEndElement();
                }
            }
        }
Example #12
0
        public void AbsoluteExpirationWorksAcrossLink()
        {
            var    clock = new TestClock();
            var    cache = CreateCache(clock);
            var    obj   = new object();
            string key   = "myKey";
            string key1  = "myKey1";

            var link = new EntryLink();

            var trigger = new TestTrigger()
            {
                ActiveExpirationCallbacks = true
            };

            cache.Set(key, link, context =>
            {
                context.SetAbsoluteExpiration(TimeSpan.FromSeconds(5));
                return(obj);
            });

            cache.Set(key1, context =>
            {
                context.AddEntryLink(link);
                return(obj);
            });

            Assert.StrictEqual(obj, cache.Get(key));
            Assert.StrictEqual(obj, cache.Get(key1));

            clock.Add(TimeSpan.FromSeconds(10));

            object value;

            Assert.False(cache.TryGetValue(key1, out value));
            Assert.False(cache.TryGetValue(key, out value));
        }
Example #13
0
        public void TriggerExpiresLinkedEntry()
        {
            var    cache = CreateCache();
            var    obj   = new object();
            string key   = "myKey";
            string key1  = "myKey1";

            var link = new EntryLink();

            var trigger = new TestTrigger()
            {
                ActiveExpirationCallbacks = true
            };

            cache.Set(key, link, context =>
            {
                context.AddExpirationTrigger(trigger);
                return(obj);
            });

            cache.Set(key1, context =>
            {
                context.AddEntryLink(link);
                return(obj);
            });

            Assert.StrictEqual(obj, cache.Get(key));
            Assert.StrictEqual(obj, cache.Get(key1));

            trigger.Fire();

            object value;

            Assert.False(cache.TryGetValue(key1, out value));
            Assert.False(cache.TryGetValue(key, out value));
        }
Example #14
0
        // Internal for unit testing
        internal void UpdateCacheContext(ICacheSetContext cacheSetContext, EntryLink entryLink)
        {
            if (ExpiresOn != null)
            {
                cacheSetContext.SetAbsoluteExpiration(ExpiresOn.Value);
            }

            if (ExpiresAfter != null)
            {
                cacheSetContext.SetAbsoluteExpiration(ExpiresAfter.Value);
            }

            if (ExpiresSliding != null)
            {
                cacheSetContext.SetSlidingExpiration(ExpiresSliding.Value);
            }

            if (Priority != null)
            {
                cacheSetContext.SetPriority(Priority.Value);
            }

            cacheSetContext.AddEntryLink(entryLink);
        }
Example #15
0
        public void UpdateCacheContext_UsesAbsoluteExpirationSpecifiedOnEntryLink()
        {
            // Arrange
            var expiresOn    = DateTimeOffset.UtcNow.AddMinutes(7);
            var cache        = new MemoryCache(new MemoryCacheOptions());
            var cacheContext = new Mock <ICacheSetContext>(MockBehavior.Strict);

            cacheContext.Setup(c => c.SetAbsoluteExpiration(expiresOn))
            .Verifiable();
            var cacheTagHelper = new CacheTagHelper
            {
                MemoryCache = cache
            };

            var entryLink = new EntryLink();

            entryLink.SetAbsoluteExpiration(expiresOn);

            // Act
            cacheTagHelper.UpdateCacheContext(cacheContext.Object, entryLink);

            // Assert
            cacheContext.Verify();
        }
Example #16
0
        public void NestedLinkContextsCanAggregate()
        {
            var    clock = new TestClock();
            var    cache = CreateCache(clock);
            var    obj   = new object();
            string key1  = "myKey1";
            string key2  = "myKey2";
            string key3  = "myKey3";

            var link1 = new EntryLink();
            var link2 = new EntryLink();

            var trigger2 = new TestTrigger()
            {
                ActiveExpirationCallbacks = true
            };
            var trigger3 = new TestTrigger()
            {
                ActiveExpirationCallbacks = true
            };

            cache.GetOrSet(key1, context1 =>
            {
                using (link1.FlowContext())
                {
                    cache.GetOrSet(key2, context2 =>
                    {
                        context2.AddExpirationTrigger(trigger2);
                        context2.SetAbsoluteExpiration(TimeSpan.FromSeconds(10));

                        using (link2.FlowContext())
                        {
                            cache.GetOrSet(key3, context3 =>
                            {
                                context3.AddExpirationTrigger(trigger3);
                                context3.SetAbsoluteExpiration(TimeSpan.FromSeconds(15));
                                return(obj);
                            });
                        }
                        context2.AddEntryLink(link2);
                        return(obj);
                    });
                }
                context1.AddEntryLink(link1);
                return(obj);
            });

            Assert.Equal(2, link1.Triggers.Count());
            Assert.NotNull(link1.AbsoluteExpiration);
            Assert.Equal(clock.UtcNow + TimeSpan.FromSeconds(10), link1.AbsoluteExpiration);

            Assert.Equal(1, link2.Triggers.Count());
            Assert.NotNull(link2.AbsoluteExpiration);
            Assert.Equal(clock.UtcNow + TimeSpan.FromSeconds(15), link2.AbsoluteExpiration);

            cache.Set(key1, context =>
            {
                context.AddEntryLink(link2);
                return(obj);
            });
        }
Example #17
0
        /// <summary>Given an xml XElement deserialize to object T.</summary>
        public T DeserializeNamedElements <T>(XElement input)
        {
            var target = Activator.CreateInstance <T>();

            if (parentCollectionOfInnerType.ContainsKey(typeof(T)) &&
                parentCollectionOfInnerType[typeof(T)].Count > 0)
            {
                foreach (PropertyInfo key in parentCollectionOfInnerType[typeof(T)].Keys)
                {
                    Type collectionType = parentCollectionOfInnerType[typeof(T)][key];

                    //since we have a handle on the collections, create a new instance since we don't know ahead
                    // of time how many results each will have
                    key.SetValue(target, (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(collectionType)));
                }
            }

            var propsByName    = new List <KeyValuePair <string, string> >();
            var elementsByName = new Dictionary <string, XElement>();

            //Use to track elements with just attributes that happen to be subobjects
            var elementsWithAttributes = new Dictionary <string, XElement>();

            foreach (var element in input.Elements())
            {
                propsByName.Add(new KeyValuePair <string, string>(element.Name.LocalName, element.Value));
                elementsByName[element.Name.LocalName] = element;
                if (element.Attributes().Count() > 0)
                {
                    if (element.Name.LocalName != "link")
                    {
                        elementsWithAttributes[element.Name.LocalName] = element;
                    }
                    else
                    {
                        var linkRel = element.Attribute("rel");

                        if (linkRel != null)
                        {
                            string linkValue = element.Attribute("href").Value;

                            if (linkRel.Value == "self")
                            {
                                propsByName.Add(new KeyValuePair <string, string>("link_self", linkValue));
                            }
                            else if (linkRel.Value == "edit")
                            {
                                propsByName.Add(new KeyValuePair <string, string>("link_edit", linkValue));
                            }
                            else if (linkRel.Value.Contains("edit-photo"))
                            {
                                propsByName.Add(new KeyValuePair <string, string>("link_edit-photo", linkValue));
                            }
                        }
                    }
                }
            }

            foreach (var att in input.Attributes())
            {
                propsByName.Add(new KeyValuePair <string, string>(att.Name.LocalName, att.Value));
            }

            if (input.Name.LocalName == "phoneNumber" && !string.IsNullOrWhiteSpace(input.Value))
            {
                propsByName.Add(new KeyValuePair <string, string>("text", input.Value));
            }

            //TODO: FIGURE OUT HOW TO GET THE EDIT LINK URL

            // Get all elements for the node
            foreach (var pair in propsByName)
            {
                if (!string.IsNullOrWhiteSpace(pair.Value) || elementsWithAttributes.ContainsKey(pair.Key))
                {
                    string ename = pair.Key;

                    //pbN[Contact][email] = property(List<Email>)
                    if (propertiesByName[typeof(T)].ContainsKey(ename))
                    {
                        //Property: Email
                        var prop = propertiesByName[typeof(T)][ename];

                        //List<Email>
                        Type targetType = prop.PropertyType;

                        if (parentCollectionOfInnerType.ContainsKey(typeof(T)) &&
                            parentCollectionOfInnerType[typeof(T)].ContainsKey(prop))
                        {
                            //Email
                            targetType = parentCollectionOfInnerType[typeof(T)][prop];
                        }

                        object result = new object(); // = Activator.CreateInstance(targetType);

                        if (targetType == typeof(string))
                        {
                            result = pair.Value;
                        }
                        else if (targetType == typeof(int?))
                        {
                            result = int.Parse(pair.Value);
                        }
                        else if (targetType == typeof(bool?))
                        {
                            result = bool.Parse(pair.Value);
                        }
                        else if (targetType == typeof(long?))
                        {
                            result = long.Parse(pair.Value);
                        }
                        else if (targetType == typeof(DateTime?))
                        {
                            result = DateTime.Parse(pair.Value);
                        }
                        else if (targetType.Namespace == typeof(T).Namespace)
                        {
                            MethodInfo method  = this.GetType().GetMethod("DeserializeNamedElements"); //TODO: Find a way not based on string?
                            MethodInfo generic = method.MakeGenericMethod(targetType);

                            result = generic.Invoke(this, new object[] { elementsByName[pair.Key] });
                        }

                        //now that we have the result, set it if it's the right type
                        if (targetType != prop.PropertyType)
                        {
                            //find the collection and add it to that
                            ((IList)prop.GetValue(target)).Add(result);
                        }
                        else
                        {
                            prop.SetValue(target, result);
                        }
                    }
                    else if (ename.StartsWith("link_"))
                    {
                        var elink = new EntryLink()
                        {
                            Rel  = pair.Key,
                            Href = pair.Value
                        };

                        var prop = propertiesByName[typeof(T)]["links"];

                        ((IList)prop.GetValue(target)).Add(elink);
                    }
                }
            }

            return(target);
        }
Example #18
0
        public void Main()
        {
            IMemoryCache cache = new MemoryCache(new MemoryCacheOptions());
            object       result;
            string       key       = "Key";
            object       newObject = new object();
            object       state     = new object();

            // Basic CRUD operations:

            // Create / Overwrite
            result = cache.Set(key, newObject);
            result = cache.Set(key, context => new object());
            result = cache.Set(key, state, context => new object());

            // Retrieve, null if not found
            result = cache.Get(key);

            // Retrieve
            bool found = cache.TryGetValue(key, out result);

            // Delete
            cache.Remove(key);

            // Conditional operations:

            // Retrieve / Create when we want to lazily create the object.
            result = cache.GetOrSet(key, context => new object());

            // Retrieve / Create when we want to lazily create the object.
            result = cache.GetOrSet(key, state, context => new object());

            // Cache entry configuration:

            // Stays in the cache as long as possible
            result = cache.GetOrSet(key, state, context =>
            {
                context.SetPriority(CachePreservationPriority.NeverRemove);
                return(new object());
            });

            // Automatically remove if not accessed in the given time
            result = cache.GetOrSet(key, state, context =>
            {
                context.SetSlidingExpiration(TimeSpan.FromMinutes(5));
                return(new object());
            });

            // Automatically remove at a certain time
            result = cache.GetOrSet(key, state, context =>
            {
                context.SetAbsoluteExpiration(new DateTime(2014, 12, 31));
                // or relative:
                // context.SetAbsoluteExpiration(TimeSpan.FromMinutes(5));
                return(new object());
            });

            // Automatically remove if not accessed in the given time
            // Automatically remove at a certain time (if it lives that long)
            result = cache.GetOrSet(key, state, context =>
            {
                context.SetSlidingExpiration(TimeSpan.FromMinutes(5));

                context.SetAbsoluteExpiration(new DateTime(2014, 12, 31));
                // or relative:
                // context.SetAbsoluteExpiration(TimeSpan.FromMinutes(5));
                return(new object());
            });

            // Callback when evicted
            result = cache.GetOrSet(key, state, context =>
            {
                context.RegisterPostEvictionCallback((echoKey, value, reason, substate) =>
                                                     Console.WriteLine(echoKey + ": '" + value + "' was evicted due to " + reason), state: null);
                return(new object());
            });

            // Remove on trigger
            var cts = new CancellationTokenSource();

            result = cache.GetOrSet(key, state, context =>
            {
                context.AddExpirationTrigger(new CancellationTokenTrigger(cts.Token));
                return(new object());
            });

            result = cache.GetOrSet(key, context =>
            {
                var link = new EntryLink();

                var inner1 = cache.GetOrSet("subkey1", link, subContext =>
                {
                    return("SubValue1");
                });

                string inner2;
                using (link.FlowContext())
                {
                    inner2 = cache.GetOrSet("subkey2", subContext =>
                    {
                        return("SubValue2");
                    });
                }

                context.AddEntryLink(link);

                return(inner1 + inner2);
            });
        }