Wrapper class for the request information
        /// <summary>
        /// Get a resource by the {CustomResource ...} markup extension
        /// </summary>
        /// <param name="resourceId">if of the resource</param>
        /// <param name="objectType">expected type of the result</param>
        /// <param name="propertyName">name of the property where the value is assigned</param>
        /// <param name="propertyType">type of the property where the value is assigned</param>
        /// <returns>value</returns>
        /// <exception cref="FakeMarkupExtensionException">Something went wrong while grabbing the value.</exception>
        protected override object GetResource(string resourceId, string objectType, string propertyName, string propertyType)
        {
            var crri     = new CustomResourceRequestInfo(resourceId, objectType, propertyName, propertyType);
            var cacheKey = resourceId + "&" + propertyType;
            // -- try getting result from cache
            Func <object> fo;

            if (_cache.TryGetValue(cacheKey, out fo))
            {
                return(fo.Invoke());
            }
            // -- nopity nope
            var tokens = resourceId.Split('$').Select(x => x.Trim()).ToArray();
            // get provider
            IFakeMarkupExtensionProvider provider;

            if (!_providers.TryGetValue(tokens[0], out provider))
            {
                throw new FakeMarkupExtensionException($"No provider found with id {tokens[0]}");
            }
            // get
            var paramTokens = tokens.Skip(1).Select(x => new FakeMarkupExtensionToken(x)).ToArray();
            var resultFunc  = provider.GetResult(crri, paramTokens);

            // return result
            if (provider.IsCacheable)
            {
                _cache[cacheKey] = resultFunc;
            }
            return(resultFunc.Invoke());
        }
 /// <summary>
 /// Get a resource by the {CustomResource ...} markup extension
 /// </summary>
 /// <param name="resourceId">if of the resource</param>
 /// <param name="objectType">expected type of the result</param>
 /// <param name="propertyName">name of the property where the value is assigned</param>
 /// <param name="propertyType">type of the property where the value is assigned</param>
 /// <returns>value</returns>
 /// <exception cref="FakeMarkupExtensionException">Something went wrong while grabbing the value.</exception>
 protected override object GetResource(string resourceId, string objectType, string propertyName, string propertyType)
 {
     var crri = new CustomResourceRequestInfo(resourceId, objectType, propertyName, propertyType);
     var cacheKey = resourceId + "&" + propertyType;
     // -- try getting result from cache
     Func<object> fo;
     if (_cache.TryGetValue(cacheKey, out fo))
     {
         return fo.Invoke();
     }
     // -- nopity nope
     var tokens = resourceId.Split('$').Select(x => x.Trim()).ToArray();
     // get provider
     IFakeMarkupExtensionProvider provider;
     if (!_providers.TryGetValue(tokens[0], out provider)) throw new FakeMarkupExtensionException($"No provider found with id {tokens[0]}");
     // get
     var paramTokens = tokens.Skip(1).Select(x => new FakeMarkupExtensionToken(x)).ToArray();
     var resultFunc = provider.GetResult(crri, paramTokens);
     // return result
     if (provider.IsCacheable) _cache[cacheKey] = resultFunc;
     return resultFunc.Invoke();
 }