Ejemplo n.º 1
0
        /// <summary>
        /// Get the string for a given key and convert to the desired type
        /// </summary>
        /// <param name="key">case insensitive key to fetch</param>
        /// <param name="default">An optional function to provide the default if the key is missing</param>
        /// <typeparam name="T">The type to convert to</typeparam>
        /// <returns>The converted value</returns>
        /// <exception cref="KeyNotFoundException">Key is not present and no default was provided</exception>
        public T Get <T>(string key, Func <T> @default = null)
        {
            var found = SettingsDictionary
                        .TryGetValue(key, Configuration, out var result);

            if (found)
            {
                return(_converter.Convert <T>(result));
            }
            else if (@default != null)
            {
                return(@default());
            }
            else
            {
                throw new KeyNotFoundException();
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Populate the properties on a provided Type that match the keys in the SettingsDictionary.
        /// </summary>
        /// <param name="target">The object to set properties on</param>
        /// <param name="requireAll">All the properties on the target must be bound, otherwise an exception is thrown</param>
        /// <param name="prefix">Defaults typeof(T).Name</param>
        /// <typeparam name="T"></typeparam>
        public void Bind <T>(T target, bool requireAll = true, string prefix = null) where T : new()
        {
            prefix = prefix ?? typeof(T).Name;
            if (prefix.Length > 0)
            {
                prefix = prefix + ".";
            }

            var props = typeof(T)
                        .GetProperties()
                        .Where(p => !(p.GetSetMethod() is null));

            foreach (var prop in props)
            {
                var    type  = prop.PropertyType;
                var    name  = $"{prefix}{prop.Name}";
                object value = null;

                if (!type.IsPrimitive &&
                    !type.IsEnum &&
                    type != typeof(string) &&
                    type != typeof(decimal) &&
                    type != typeof(DateTime))
                {
                    value = this.GetType().GetMethods()
                            .Where(x => x.Name == "Bind" && x.GetParameters()?.Length == 2)
                            .FirstOrDefault()?
                            .MakeGenericMethod(type)?
                            .Invoke(this, new object[] { requireAll, name });
                }
                else if (SettingsDictionary.TryGetValue(name, Environment, out var result) || requireAll)
                {
                    value = Get(type, name);
                }

                if (!(value is null))
                {
                    prop.SetValue(
                        target,
                        value
                        );
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Method to retrieve value either from the settings dictionary or from cache. Uses recursion to get nested class values
        /// </summary>
        /// <param name="prop">Property of class that a value is to be returned</param>
        /// <param name="name">Name of settings dictionary key that is linked to property</param>
        /// <param name="preload">Determines if the call is from a preload event or not</param>
        /// <param name="requireAll">Determines if all properties of the binding class should have a matching settings dictionary key and value</param>
        /// <returns></returns>
        private IBindResult GetPropertyValue(PropertyInfo prop, string name, bool preload, bool requireAll)
        {
            object value  = null;
            var    errors = new List <string>();

            if (IsNestedProperty(prop.PropertyType))
            {
                // Get nested property value via recursion
                var valObjectResult = GetType()
                                      .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
                                      .FirstOrDefault(x => x.Name == nameof(Settings.GetBindResult) && x.GetParameters()?.Length == 4)?
                                      .MakeGenericMethod(prop.PropertyType)
                                      .Invoke(this, new object[] { requireAll, name, false, errors });

                if (valObjectResult is IBindResult typedResult)
                {
                    if (typedResult.Errors?.Any() ?? false)
                    {
                        errors.AddRange(typedResult.Errors);
                    }

                    value = typedResult.Result;
                }
            }
            // When the call is not for a preload event and it is not nested, attempt to get a value
            else if (preload)
            {
                var getter = prop.GetGetMethod();
                if (getter == null)
                {
                    return(null);
                }

                value = getter.Invoke(this, Array.Empty <object>());
            }

            // When the value is still null, last chance call to check if there is a value in the settings dictionary
            if (value is null && SettingsDictionary.TryGetValue(name, Environment, out var result) || requireAll)
            {
                value = Get(prop.PropertyType, name);
            }

            return(new BindResultBase(errors, value));
        }