Hello everyone!
I've run into a strange problem - I can't proparly save and ready dictionaries and my own custom classes form the Config.
Here is what I'm trying to do:
I have something like this:
And what I wanted is to save it to the config and read it back.Code:private Dictionary<string, string> dict1; private Dictionary<string, string> dict2;
This is the code I'm using to get data in\out of config:
Fill dicts with something and trying to get it to config, and I expect it to work:Code:private void GetConfig<T>(string Key, ref T var) { if (Config[Key] != null) { var = (T)Convert.ChangeType(Config[Key], typeof(T)); } Config[Key] = var; }
But here comes an error-Code:private void LoadConfigValues() { dict1 = new Dictionary<string, string>() { ["Test1"] = "test1", ["Test2"] = "test2" } dict2 = new Dictionary<string, string>() { ["Test3"] = "test3", ["Test4"] = "test4" } GetConfig("Dictionary 1", ref dict1); Getconfig("Dictionary 2", ref dict2); SaveConfig(); }So the problem is - Config[Key] returns me not Dictionary<string,string>, but Dictionary<string,object>Code:Failed to initialize plugin 'test v1.0.0' (InvalidCastException: Value is not a convertible object: System.Collections.Generic.Dictionary`2[System.String,System.Object] to System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]])
How can I avoid it?
The only solution I've found so far is doing something creepy like that:
And that's creepy.Code:private Dictionary<string, string> Dict1; private Dictionary<string, string> Dict2;private void LoadConfigValues() { Dictionary<string, object> dict1 = new Dictionary<string, object>() { ["Test1"] = "test1", ["Test2"] = "test2" } Dictionary<string, object> dict2 = new Dictionary<string, object>() { ["Test3"] = "test3", ["Test4"] = "test4" } GetConfig("Dictionary 1", ref dict1); Getconfig("Dictionary 2", ref dict2); foreach(var item in dict1) { Dict1.Add(item.Key, item.Value.ToString()); } foreach(var item in dict2) { Dict2.Add(item.Key, item.Value.ToString()); } SaveConfig();}
About classes - that's the over question.
Let's say I have a class:
Is there any way to store it?Code:class DnN { public Dictionary<string, object> Day { get; set; } public Dictionary<string, object> Night { get; set; } public DnN() { Day = new Dictionary<string, object>(); //Same problem as above, so this time I decided to just Night = new Dictionary<string, object>(); // Change Dictionaty<string,float> to <string,object> } }
[DOUBLEPOST=1492192679][/DOUBLEPOST]Also - if anyone would be able to tell me why this code works:
While this(just to be able to save config into the sub directories) gives me cast error:Code:private void GetConfig<T>(string Key, ref T var) { if (Config[Key] != null) { var = (T)Convert.ChangeType(Config[Key], typeof(T)); } Config[Key] = var; }
Code:private void GetConfig<T>(ref T value, params object[] args) { List<string> stringArgs = (from arg in args select arg.ToString()).ToList<string>(); if (Config.Get(stringArgs.ToArray()) != null) { value = (T)Convert.ChangeType(Config.Get(stringArgs.ToArray()), typeof(T)); } Config.Set(args, value); }
Saving and reading dictionaries and custom classes from config
Discussion in 'Rust Development' started by Vlad-00003, Apr 14, 2017.
-
Ooook.... for thoses who would got here - here is an example how to do so - classes.
So, here is an example of saving classes to the DynamicConfigFile:
Code:using Newtonsoft.Json; //Code private PluginConfig config; //notice that my var starts from lower case. Config - in-build var of type DynamicConfigFile with the name of the plugin. //Code #region Config private class PluginConfig { [JsonProperty("This is the text, that would be assossiated with the config line")] public string Permission; [JsonProperty("Is it working?")] public bool IsIt; [JsonProperty("Here is some description of this variable")] public DealWithIt DoYou; public static PluginConfig DefaultConfig() { Permission = "coolplugin.use", IsIt = true, DoYou = new DealWithIt(){ { Yeah = true, Nope = false } }; } private class DealWithIt { [JsonProperty("Description of sub var 1")] public bool Yeah; [JsonProperty("Description of sub var 2")] public bool Nope; } #endregion#region Config init protected override void LoadDefaultConfig() { PrintWarning("Generating default config file"); config = PluginConfig.DefaultConfig(); //we don't have to save config to the file yet - due to override SaveConfig function } protected override void LoadConfig() { base.LoadConfig(); //we have loaded config file, now - reading it as the object and doing what we want wile loading config file. config = Config.ReadObject<PluginConfig>(); permission.RegisterPermission(config.Permission, this); } protected override void SaveConfig() { //Using WriteObject to store out object to the file. Config.WriteObject(config); } #endregion
-
If you want to save just a dictionary, or list, or any over build-in classes and objects - you can use this construction:
Code:private Dictionary<string,List<string>> mydict; #region Config Initialization protected override void LoadDefaultConfig() { PrintWarning("New config file created"); mydict = new Dictionary<string,List<string>>() { ["string 1"] = new List<string>() { "substring 1_1","substring 1_2","substring 1_3" }, ["string 2"] = new List<string>() { "substring 2_1","substring 2_2","substring 2_3" }, } } protected override void LoadConfig() { base.LoadConfig(); mydict = Config.ReadObject<Dictionary<string,List<string>>>(); foreach(var str in mydict.Keys) permission.RegisterPermission(str, this); } protected override void SaveConfig() { Config.WriteObject(config); } #endregion
Code:private Dictionary<string, bool> MyDict = new Dictionary<string, bool>(); private void SaveData() { Interface.Oxide.DataFileSystem.WriteObject(Title, MyDict); } void LoadData() { try { MyDict = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, bool>>(Title); } catch (Exception ex) { PrintError($"Failed to load data file (is the file corrupt?) ({ex.Message})"); MyDict = new Dictionary<string, bool>(); } }
-
Hey, @Wulf , why my post is awaiting for the approval? there is no even a links in there....
Also - maybe you can add this to the docs? As well as the chat\console commands? Cos there is only covalence [Command] Listed there....
And JsonProperty - this is something not much people know =)
P.S. Ok, my mistake. link removed. Didn't notice it. This was just a copy-paste from one of my plugin)
P.P.S - I didn't see the thread tools for some reason, and can't put prefix on it, so...