public async Task <TreeNode <NavigationNode> > GetTree()
        {
            // ultimately we will need to cache sitemap per site
            // we will implement a custom ICacheKeyResolver to resolve multi tenant cache keys

            if (rootNode == null)
            {
                log.LogDebug("rootnode was null so checking cache");
                string cacheKey = cacheKeyResolver.ResolveCacheKey(options.CacheKey);

                rootNode = (TreeNode <NavigationNode>)cache.Get(cacheKey);

                if (rootNode == null)
                {
                    log.LogDebug("rootnode was not in cache so building");
                    rootNode = await implementation.GetTree();

                    if (rootNode != null)
                    {
                        cache.Set(
                            cacheKey,
                            rootNode,
                            new MemoryCacheEntryOptions()
                            .SetSlidingExpiration(TimeSpan.FromSeconds(options.CacheDurationInSeconds)));
                    }
                }
                else
                {
                    log.LogDebug("rootnode was found in cache");
                }
            }

            return(rootNode);
        }
        public async Task <TreeNode <NavigationNode> > GetTree()
        {
            // ultimately we will need to cache sitemap per site
            // we will implement a custom ICacheKeyResolver to resolve multi tenant cache keys

            if (rootNode == null)
            {
                log.LogDebug("rootnode was null so checking distributed cache");
                string cacheKey = cacheKeyResolver.ResolveCacheKey(options.CacheKey);

                NavigationTreeXmlConverter converter = new NavigationTreeXmlConverter();

                await cache.ConnectAsync();

                byte[] bytes = await cache.GetAsync(cacheKey);

                if (bytes != null)
                {
                    log.LogDebug("rootnode was found in distributed cache so deserializing");
                    string    xml = Encoding.UTF8.GetString(bytes);
                    XDocument doc = XDocument.Parse(xml);

                    rootNode = converter.FromXml(doc);
                }
                else
                {
                    log.LogDebug("rootnode was not in cache so building");

                    rootNode = await implementation.GetTree();

                    string xml2 = converter.ToXmlString(rootNode);

                    await cache.SetAsync(
                        cacheKey,
                        Encoding.UTF8.GetBytes(xml2),
                        new DistributedCacheEntryOptions().SetSlidingExpiration(
                            TimeSpan.FromSeconds(options.CacheDurationInSeconds))
                        );
                }
            }

            return(rootNode);
        }