/// <summary> /// Gets the file data for the specified resource, storing a cached version if specified /// IMPORTANT: /// NOTE: Make sure any and all await calls inside this function and its children /// use ConfigureAwait(false). This is because the parent has to support /// a synchronous version of this call, so the method cannot sync back with /// its calling context without risk of deadlock. /// </summary> /// <param name="pathFormat">The path to the desired resource, containing {0} in place of the culture</param> /// <param name="constructData">The function that takes the file data and converts it into the format required by the provider</param> /// <param name="culture">The culture to use. If not specified, the default culture is used</param> /// <returns></returns> protected async Task <T> GetResourceDocumentAsync <T>(ResourceDefinition pathFormat, Func <Stream, T> constructData, string culture = null) { try { await mSelfLock.WaitAsync(); // Get culture path var resourcePath = ResourceFormatProviderHelpers.GetCulturePath(pathFormat.Location, culture); // Make sure list has been initialized if (mCache == null) { mCache = new Dictionary <string, object>(); } // If we have a document already, return that if (mCache.ContainsKey(resourcePath)) { return((T)mCache[resourcePath]); } // Otherwise try and get it var resourceDocument = default(T); try { // Try to get the stream for this resource using (var stream = await ResourceFormatProviderHelpers.GetStreamAsync(pathFormat.Type, resourcePath).ConfigureAwait(false)) { // If successful, try and convert that data into a usable resource object if (stream != null) { resourceDocument = constructData(stream); } } } finally { // Add resource document if found or not (except for Urls, never add failed Urls in case of bad Internet connection if (mCacheResourceFiles && pathFormat.Type != ResourceDefinitionType.Url) { mCache.Add(resourcePath, resourceDocument); } } // Return what we found, if anything return(resourceDocument); } finally { mSelfLock.Release(); } }
/// <summary> /// Finds a string of the given name, taking into account the culture information. /// If no culture is specified, the default culture is used /// /// IMPORTANT: /// NOTE: Make sure any and all await calls inside this function and its children /// use ConfigureAwait(false). This is because the parent has to support /// a synchronous version of this call, so the method cannot sync back with /// its calling context without risk of deadlock. /// </summary> /// <param name="name">The name of the resource to find</param> /// <param name="culture">The culture information to use</param> /// <returns>Returns the string if found, or null if not found</returns> public async Task <string> GetStringAsync(string name, string culture = null) { // Make sure we have a string format if (StringResourceDefinition == null) { return(null); } // If we have no providers we cannot do anything if (Providers == null) { return(null); } // Get file format if specified var format = ResourceFormatProviderHelpers.GetFormat(StringResourceDefinition); // Find a provider that supports the format var supportedProviders = Providers.Where(f => f.SupportsFormat(format)); // If we have no supported format providers, return null if (supportedProviders.Count() == 0) { return(null); } // Now that we have format providers, attempt to get the value from one, stopping as soon as one is successful string value = null; foreach (var provider in supportedProviders) { if (await provider.GetStringAsync(StringResourceDefinition, name, culture, (result) => { value = result; }).ConfigureAwait(false)) { break; } } // Return whatever value we found return(value); }