/// <summary>
 /// Надстройка для получения ресурсов через this с кешированием и по имени метода из консоли, а не только по имени ресурса.
 /// </summary>
 protected object ReadResource(Type resourceType, string resourceName, ReadResourseOptions options = null,
                               [CallerMemberName] string memberName = null)
 {
     //Включаем автосчитывание если нужно
     options = options ?? new ReadResourseOptions();
     return(Cmd.ReadResource(resourceType, memberName + "." + resourceName, options));
 }
        object readResource(Type objectType, int tryesCount, string resourceName, ReadResourseOptions options, object defaultValue)
        {
            if (options == null)
            {
                options = new ReadResourseOptions();
            }
            string hint        = options.Hint;
            var    longResName = resourceName + "";

            try
            {
                this.WriteLine($"Resource '{longResName}' with type {objectType} requested from console.", ConsoleColor.Yellow);
                if (!string.IsNullOrWhiteSpace(hint))
                {
                    this.WriteLine($"Hint: {hint}", ConsoleColor.Yellow);
                }

                string cachedValueString = StorageHardDrive.Get <string>(longResName).Result;

                if (typeof(IConvertible).IsAssignableFrom(objectType))
                {
                    return(IfResourceIsIConvertible(objectType, longResName, cachedValueString, options));
                }
                else
                {
                    return(IfResourceIsDifficult(objectType, longResName, cachedValueString, defaultValue, options));
                }
            }
            catch (Exception ex)
            {
                if (ThrowConsoleParseExeptions || tryesCount < 0)
                {
                    throw;
                }
                else
                {
                    this.WriteLine("Exeption in console resource receiving method: ", ConsoleColor.DarkRed);
                    this.WriteLine(("\t" + ex.Message).Replace("\n", "\n\t"));

                    //try again
                    return(readResource(objectType, tryesCount - 1, resourceName, options, defaultValue));
                }
            }
        }
 /// <summary>
 /// Надстройка для получения ресурсов через this с кешированием и по имени метода из консоли, а не только по имени ресурса.
 /// </summary>
 protected T ReadResource <T>(string resourceName, ReadResourseOptions options = null,
                              [CallerMemberName] string memberName             = null)
 {
     return((T)ReadResource(typeof(T), resourceName, options, memberName));
 }
        object IfResourceIsIConvertible(Type objectType, string longResName, string cachedValueString, ReadResourseOptions options)
        {
            //If IConvertible
            //
            string cachedValue       = cachedValueString;
            var    cachedValueInHint = cachedValue ?? "";

            if (cachedValueInHint.Length > 80)
            {
                cachedValueInHint = cachedValueInHint.Substring(0, 80) + "... ";
            }

            this.Write(
                $"Input ({cachedValueInHint}): ",
                ConsoleColor.Yellow
                );

            //Если автоматическое считывание, то возвращаем закешированное значение.
            string val = "";

            if (!options.UseAutoread)
            {
                val = this.ReadLine();
            }


            if (val == "" && cachedValue != null)
            {
                val = cachedValue;
            }
            else
            {
                if (options.SaveToCache)
                {
                    StorageHardDrive.Set(longResName, val);
                }
            }


            object res = null;

            if (objectType == typeof(bool) || objectType == typeof(bool?))
            {
                val = val.Trim();
                if (val == "y")
                {
                    res = true;
                }
                if (val == "n")
                {
                    res = false;
                }
            }
            if (res == null)
            {
                res = Convert.ChangeType(val, objectType);
            }
            return(res);
            //
            //If IConvertible
        }
        object IfResourceIsDifficult(Type objectType, string longResName, string cachedValueString, object defaultValue, ReadResourseOptions options)
        {
            //Else, will be converted by json.
            //
            this.WriteLine(
                $"Difficult type. Will be opened in json editor. ",
                ConsoleColor.Yellow
                );

            object cachedValue;

            try
            {
                if (defaultValue == null)
                {
                    cachedValue = JsonSerializeHelper.Inst.FromJson(objectType, cachedValueString);
                }
                else
                {
                    cachedValue = defaultValue;
                }
            }
            catch
            {
                ConstructorInfo ctor = objectType.GetConstructor(new Type[] { });
                cachedValue = ctor.Invoke(new object[] { });
            }

            //Если автоматическое считывание, то возвращаем закешированное значение.
            if (options.UseAutoread)
            {
                return(cachedValue);
            }

            this.ReadLine();

            bool   isAccept;
            string editedJson          = null;
            string jsonPrototypeString = JsonSerializeHelper.Inst.ToJson(
                objectType,
                cachedValue,
                new JsonSerializeOptions()
            {
                WithNormalFormating = true
            }
                );

            do
            {
                editedJson = ConsoleHandler.ReadJson(jsonPrototypeString);



                this.Write("Accept changes? Press y/n (y): ", ConsoleColor.Yellow);
                isAccept = this.ReadLine().Trim().StartsWith("n");
            } while (isAccept);


            object res = JsonSerializeHelper.Inst.FromJson(objectType, editedJson);

            //Convert again to normal parse json.
            if (options.SaveToCache)
            {
                StorageHardDrive.Set(longResName, JsonSerializeHelper.Inst.ToJson(objectType, res));
            }
            return(res);
            //
            //Else, will be converted by json.
        }
 /// <summary>
 /// Запрашивайте данные от пользователя ТОЛЬКО ЧЕРЕЗ ЭТОТ МЕТОД.
 /// Если запрашиваемый тип реализует IConvertible, то он будет запрошен через консоль. Иначе - пользователю дадут отредактировать Json файл.
 /// <para></para>
 /// Еще этот метод может кешировать значение по имени ресурса, используя его можно с легкостью реализовать астозаполнение и даже автоматическое тестирование.
 /// </summary>
 public object ReadResource(Type typeOfResource, string resourceName, ReadResourseOptions options = null)
 {
     return(readResource(typeOfResource, 10, resourceName, options, null));
 }
 /// <summary>
 /// Запрашивайте данные от пользователя ТОЛЬКО ЧЕРЕЗ ЭТОТ МЕТОД.
 /// Если запрашиваемый тип реализует IConvertible, то он будет запрошен через консоль. Иначе - пользователю дадут отредактировать Json файл.
 /// <para></para>
 /// Еще этот метод может кешировать значение по имени ресурса, используя его можно с легкостью реализовать астозаполнение и даже автоматическое тестирование.
 /// </summary>
 public T ReadResource <T>(string resourceName, ReadResourseOptions options = null)
 {
     return((T)readResource(typeof(T), 10, resourceName, options, default(T)));
 }