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(); }
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); }); }
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); }); }
/// <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; }
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); }
Label this[string k] { get { if (!EntryLink.ContainsKey(k)) { return(null); } return(EntryLink[k]); } }
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); }
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(); } } }
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)); }
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)); }
// 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); }
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(); }
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); }); }
/// <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); }
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); }); }