Beispiel #1
0
        /// <summary>
        /// Retrieves a setting
        /// </summary>
        /// <param name="services">The collection of lookup services</param>
        /// <param name="name">The name of the setting to retrieve</param>
        /// <param name="defaultValue">If the setting is not found, or there is an error retrieving the setting, this will be returned instead</param>
        /// <returns>The string setting (If you need to convert to something else, that will be done outside this call)</returns>
        public static string Get(ILookupServices <T, TS> services, string name, string defaultValue)
        => SafeTry.IgnoreException(
            () =>
        {
            var service = services.Service;
            if (service.Key == null)
            {
                return(defaultValue);
            }

            var cachingSeconds = CachingSeconds(service);

            // Get the collection of settings inside a Lock (this is possibly recursive, so can't use semaphore locking)
            var settingsCollection = NamedLocker.Lock($"{service.Key}_Locker",
                                                      num => num > 1
                            ? null // If recursive (will be allowed in lock again), the default value will be used instead of a real lookup
                            : GetItems(cachingSeconds, service, services.Cache));

            // If the above failed to find anything (eg. no settings, or a recursive call)
            if (settingsCollection.IsDefault())
            {
                return(defaultValue);
            }

            // Return the setting value (or default if no setting exists)
            var setting = service.GetItem(settingsCollection, name);
            return(setting.IsDefault() ? defaultValue : service.GetValue(setting));
        },
            defaultValue
            );
Beispiel #2
0
        /// <inheritdoc />
        /// <summary>
        /// Attempts to retrieve an item from cache.
        /// If not found in cache, will make callback to obtain the item from the caller which will be stored for later use
        /// </summary>
        /// <typeparam name="T">The type of item</typeparam>
        /// <param name="key">Name of the item in cache</param>
        /// <param name="method">The callback function returning the item if not initially found in cache</param>
        /// <returns>The object from cache/callback function</returns>
        public virtual T Get <T>(string key, Func <T> method)
        {
            if (Get(key, out T item))
            {
                return(item);
            }

            return(NamedLocker.Lock(key, num =>
            {
                if (Get(key, out item))
                {
                    return item;
                }

                item = method();

                if (Options.DoNotCacheDefault && item.IsDefault())
                {
                    return item;
                }
                // Also handles nulls, in case DoNotCacheDefault = false
                if (Options.DoNotCacheEmptyList && item is IEnumerable e && !e.GetEnumerator().MoveNext())
                {
                    return item;
                }

                Set(key, item);
                return item;
            }));
Beispiel #3
0
        private void SetOrder()
        {
            if (Order != null)
            {
                return;
            }

            // Get the prefix string from the request
            Order = SafeTry.IgnoreException(() => Info.LogOrderPrefix) ?? "";

            // Each request will increment this request property
            const string key = "logging_order";

            // I don't think this lock is really necessary, as most everything will occur on main thread so this will be synchronous.
            // But leaving lock in case a thread is trying to log something
            Order += NamedLocker.Lock($"{key}_{Info.RequestId}", num => Info.LoggingOrder++);
        }