Nucs / JsonSettings

This library simplifies creating configuration for your C# app/service by utilizing the serialization capabilities of Json.NET to serialize nested (custom) objects, dictionaries and lists as simply as by creating a POCO and inheriting JsonSettings class.
MIT License
76 stars 18 forks source link

[Feature Request] versioning setting file #19

Closed ghost1372 closed 3 years ago

ghost1372 commented 3 years ago

Suppose we have a setting file with a string property

public class Configs : JsonSettings
    {
        public override string FileName { get; set; } = "config.json";

        public virtual string Test { get; set; }

    }

If we change this property to an integer

public virtual int Test { get; set; }

and If we run the program, we get an error, which is predictable.

I suggest adding a feature like versioning setting file To delete the previous settings file. And use the new file if the settings file changes. (It would be great if the previously saved settings could be transferred to a new file).

I use the following solution and if changes are made to the settings file I will delete the previous file and create a new file

public class Configs : JsonSettings
    {
        public override string FileName { get; set; } = "config.json";

        public virtual string Test { get; set; }
        public virtual int Version { get; set; } = 13991222;

public Configs()
        {
            Version = 14000101;
        }
    }
public App()
        {
            if (!Settings.Version.Equals(RegistryHelper.GetValue<int>(Consts.VersionKey, Consts.AppName)))
            {
                if (File.Exists(Consts.ConfigPath))
                {
                    File.Delete(Consts.ConfigPath);
                }
                RegistryHelper.AddOrUpdateKey(Consts.VersionKey, Consts.AppName, Settings.Version);

                Settings = JsonSettings.Load<Configs>().EnableAutosave();
            }
        }

An overridden property such as a FileName can be useful for doing this

public class Configs : JsonSettings
    {
        public override string FileName { get; set; } = "config.json";
        public override int FileVersion { get; set; } = 1;

        public virtual string Test { get; set; }
    }
ghost1372 commented 3 years ago

I tested this feature but it seems there is an issue

public class Configs : JsonSettings, IVersionable
    {
        public override string FileName { get; set; } = "config.json";

        public virtual string MyProperty2 { get; set; }
        public virtual Version Version { get; set; }
    }

and

public Configs Settings = JsonSettings.Configure<Configs>("versioning.json")
                                   .WithVersioning("2.1.1.7", VersioningResultAction.RenameAndReload,
                                                   (version, expectedVersion) => version?.Equals(expectedVersion) == true)
                                   .LoadNow()
                                   .EnableAutosave();

For the first time MyProperty2 is the string type I run the program and set some value Settings.MyProperty2 = "test";

now i change MyProperty2 type to int And I upgrade the WithVersioning number, for example WithVersioning("3.2.2.8"... I run the program and I encounter an error

Newtonsoft.Json.JsonReaderException: 'Could not convert string to integer: test. Path 'MyProperty2', line 1, position 39.'

Did I not understand the meaning of this feature correctly? Or something is not working properly? Or have I forgotten something?

ghost1372 commented 3 years ago

@Nucs I noticed that if we use the json extension in the file name, we'll be in trouble. JsonSettings.Configure<Configs>("versioning.json") This will cause the program to crash but JsonSettings.Configure<Configs>("versioning.jsn") It works without any problems Pay attention to the json and jsn extensions

Nucs commented 3 years ago

Json.NET fails on trying to parse the old version and VersionModule is not handling that fail in any way. I'll look into that.

Nucs commented 3 years ago

I've added RecoveryModule which takes care of any exceptions. By calling this, you'll make sure the parsing error is caught and handled. Will be released on alpha4.

public Configs Settings = JsonSettings.Configure<Configs>("versioning.json")
                              .WithRecovery(RecoveryAction.LoadDefault) //action will take place only on failed parse
                              .WithVersioning("2.1.1.7", VersioningResultAction.RenameAndLoadDefault) //awill take place on mismatched version
                              .LoadNow()
                              .EnableAutosave();
ghost1372 commented 3 years ago

Thank you @Nucs Everything works well Is it possible to change the version number only in the config class? Use public virtual Version Version { get; set; } = new Version(1, 0, 0, 6);

.WithVersioning(VersioningResultAction.RenameAndLoadDefault) instead of .WithVersioning("2.1.1.7", VersioningResultAction.RenameAndLoadDefault) In this case, the way to use the module is also easier and the possibility of mistakes in the version number is also reduced

Anyway, thank you again.

Nucs commented 3 years ago

Create a separate issue for that please as this is solved, I'll respond there.