IMemoryCache

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMemoryCache();
        services.AddMvc();
    }
}
public class HomeController : Controller
{
    private IMemoryCache _cache;

    public HomeController(IMemoryCache memoryCache)
    {
        _cache = memoryCache;
    }

	public IActionResult CacheTryGetValueSet()
	{
		DateTime cacheEntry;
    
        // Look for cache key.
        if (!_cache.TryGetValue(CacheKeys.Entry, out cacheEntry))
        {
            // Key not in cache, so get data.
            cacheEntry = DateTime.Now;
    
            var cacheEntryOptions = new MemoryCacheEntryOptions()
                // Keep in cache for this time, reset time if accessed.
                .SetSlidingExpiration(TimeSpan.FromSeconds(3));

            _cache.Set(CacheKeys.Entry, cacheEntry, cacheEntryOptions);
        }    
        return View("Cache", cacheEntry);
    }
	
	public IActionResult CacheGet()
	{
		var cacheEntry = _cache.Get<DateTime?>(CacheKeys.Entry);
		return View("Cache", cacheEntry);
	}

	public IActionResult CacheGetOrCreate()
	{
		var cacheEntry = _cache.GetOrCreate(CacheKeys.Entry, entry =>
		{
			entry.SlidingExpiration = TimeSpan.FromSeconds(3);
			return DateTime.Now;
		});

		return View("Cache", cacheEntry);
	}

	public async Task<IActionResult> CacheGetOrCreateAsync()
	{
		var cacheEntry = await _cache.GetOrCreateAsync(CacheKeys.Entry, entry =>
		{
			entry.SlidingExpiration = TimeSpan.FromSeconds(3);
			return Task.FromResult(DateTime.Now);
		});

		return View("Cache", cacheEntry);
	}
}

MemoryCacheEntryOptions

public IActionResult CreateCallbackEntry()
{
    var cacheEntryOptions = new MemoryCacheEntryOptions()        
        .SetPriority(CacheItemPriority.NeverRemove)        
        .RegisterPostEvictionCallback(callback: EvictionCallback, state: this);

    _cache.Set(CacheKeys.CallbackEntry, DateTime.Now, cacheEntryOptions);

    return RedirectToAction("GetCallbackEntry");
}

public IActionResult GetCallbackEntry()
{
    return View("Callback", new CallbackViewModel
    {
        CachedTime = _cache.Get<DateTime?>(CacheKeys.CallbackEntry),
        Message = _cache.Get<string>(CacheKeys.CallbackMessage)
    });
}

public IActionResult RemoveCallbackEntry()
{
    _cache.Remove(CacheKeys.CallbackEntry);
    return RedirectToAction("GetCallbackEntry");
}

private static void EvictionCallback(object key, object value,
    EvictionReason reason, object state)
{
    var message = $"Entry was evicted. Reason: {reason}.";
    ((HomeController)state)._cache.Set(CacheKeys.CallbackMessage, message);
}

Cache Dependencies

public IActionResult CreateDependentEntries()
{
    var cts = new CancellationTokenSource();
    _cache.Set(CacheKeys.DependentCTS, cts);

    using (var entry = _cache.CreateEntry(CacheKeys.Parent))
    {
        // expire this entry if the dependant entry expires.
        entry.Value = DateTime.Now;
        entry.RegisterPostEvictionCallback(DependentEvictionCallback, this);
        _cache.Set(CacheKeys.Child, DateTime.Now, new CancellationChangeToken(cts.Token));
    }
    return RedirectToAction("GetDependentEntries");
}

public IActionResult GetDependentEntries()
{
    return View("Dependent", new DependentViewModel
    {
        ParentCachedTime = _cache.Get<DateTime?>(CacheKeys.Parent),
        ChildCachedTime = _cache.Get<DateTime?>(CacheKeys.Child),
        Message = _cache.Get<string>(CacheKeys.DependentMessage)
    });
}

public IActionResult RemoveChildEntry()
{
    _cache.Get<CancellationTokenSource>(CacheKeys.DependentCTS).Cancel();
    return RedirectToAction("GetDependentEntries");
}

private static void DependentEvictionCallback(object key, object value,
    EvictionReason reason, object state)
{
    var message = $"Parent entry was evicted. Reason: {reason}.";
    ((HomeController)state)._cache.Set(CacheKeys.DependentMessage, message);
}

ASP.NET Core MemoryCache - GetOrCreate calls factory method multiple times - .NET BLOG

Distributed Cache