Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > Coding Releases > Coding Snippets
You last visited: Today at 05:39

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[C#] Dynamic Config Class

Discussion on [C#] Dynamic Config Class within the Coding Snippets forum part of the Coding Releases category.

Reply
 
Old   #1



 
Shawak's Avatar
 
elite*gold: 0
The Black Market: 259/0/0
Join Date: Apr 2010
Posts: 10,291
Received Thanks: 3,611
[C#] Dynamic Config Class

Hello,

i'll release my little config class for people who don't want to use the .net settings.

Code:
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;

class Config
{
    // Config starts here

    public static string Username = "Spieler";
    public static int Port = 28282;


    // End of config, don't change anything below
    static BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Static;
    static FileInfo configFileInfo = new FileInfo(Constant.ConfigFile);

    public static void Load()
    {
        // Check if file existts
        if (!configFileInfo.Exists)
            return;

        // Deserialize from file
        var json = File.ReadAllText(configFileInfo.FullName, Encoding.ASCII);
        var jObject = JsonConvert.DeserializeObject<Config>(json);

        // Create temp config
        var tmpConf = new Dictionary<string, object>();
        foreach (var field in jObject.GetType().GetFields(bindingFlags))
            tmpConf.Add(field.Name, field.GetValue(null));

        // Load values from temp config
        foreach (var field in typeof(Config).GetFields(bindingFlags))
            field.SetValue(field.Name, tmpConf[field.Name]);
    }

    public static void Save()
    {
        // Create configwith values
        var tmpConf = new Dictionary<string, object>();
        foreach (var v in typeof(Config).GetFields(bindingFlags))
            tmpConf[v.Name] = v.GetValue(null);

        // Serialize to file
        var json = JsonConvert.SerializeObject(tmpConf, Formatting.Indented);
        File.WriteAllText(configFileInfo.FullName, json);
    }
}
You will need the libary to run it or you will have to write your own (de-)serialization methods.

To load the config simply use:
Code:
Config.Load();
Later in your code you can use for example:

Code:
Console.WriteLine(Config.Username);
Config.Username = "Another Username";
Console.writeLine(Config.Username);
To save your config use:

Code:
Config.Save();
The benefetifs of this class is, that your variables have strong name and type declaration, standard values and you can simply add new variables.

Lg,
Shawak
Shawak is offline  
Old 10/04/2014, 06:37   #2
 
tolio's Avatar
 
elite*gold: 2932
The Black Market: 169/1/0
Join Date: Oct 2009
Posts: 6,966
Received Thanks: 1,097
durchaus nett aber warum nicht einfach nen config object machen zb nen Dictionary und das ganze mit nem speichern und laden

Code:
Dictionary<String, Object> config = new Dictionary<String, Object>();

using(FileStream fs = new FileStream("file.dat", FileMode.Create)){
   BinaryFormatter bf = new BinaryFormatter();
   bf.Serialize(fs, config);
}

using(FileStream fs = new FileStream("file.dat", FileMode.Open)){
   BinaryFormatter bf = new BinaryFormatter();
   config = (Dictionary<String, Object>)bf.Deserialize(fs);
}
dann benötigt das ganze keine extra lib, keine teuren reflection operationen*, einiges weniger an code und das framework erledigt die arbeit

*hab nicht im framework gegraben wie das ganze implementiert ist
tolio is offline  
Thanks
1 User
Old 10/04/2014, 12:40   #3


 
elite*gold: 1091
Join Date: Jun 2007
Posts: 19,836
Received Thanks: 7,180
Quote:
Originally Posted by tolio View Post
keine teuren reflection operationen
In der Tat, du definierst ja (sofern du das ISerializable interface implementierst) direkt welche Werte unter welchen Keys abgespeichert werden und kannst dabei auch noch den Type festlegen. Da läuft nicht viel mit Reflection.
Mostey is offline  
Old 10/04/2014, 15:54   #4



 
Shawak's Avatar
 
elite*gold: 0
The Black Market: 259/0/0
Join Date: Apr 2010
Posts: 10,291
Received Thanks: 3,611
@tolio: Durchaus, aber leider gehen dir dann die Variablen Typen verloren, außerdem kann es dazu kommen, dass ein Integer als Long geladen wird oder Ähnliches.
Shawak is offline  
Old 10/04/2014, 17:37   #5


 
elite*gold: 1091
Join Date: Jun 2007
Posts: 19,836
Received Thanks: 7,180
Quote:
Originally Posted by Shawak View Post
@tolio: Durchaus, aber leider gehen dir dann die Variablen Typen verloren, außerdem kann es dazu kommen, dass ein Integer als Long geladen wird oder Ähnliches.
Nein.



Code:
protected Person(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
                throw new System.ArgumentNullException("info");
            name_value = (string)info.GetValue("AltName", typeof(string));
            ID_value = (int)info.GetValue("AltID", typeof(int));
        }
Code:
public virtual void GetObjectData(
        SerializationInfo info, StreamingContext context)
        {
            if (info == null)
                throw new System.ArgumentNullException("info");
            info.AddValue("AltName", "***");
            info.AddValue("AltID", 9999);
        }
Mostey is offline  
Old 10/04/2014, 19:06   #6
 
tolio's Avatar
 
elite*gold: 2932
The Black Market: 169/1/0
Join Date: Oct 2009
Posts: 6,966
Received Thanks: 1,097
das mit der reflection bezog sich auf den fieldinfo.get/setvalue aufruf, aber wie gesagt da ich nicht gegraben hab was das framework standardmäßig macht will ich mich da auch nicht zu weit aus dem fenster lehnen

@Shawak, nur weil ich das ganze in dem bsp mit dem dict<string, obj> im zweifel zu nem objekt boxe, bedeutet das das nicht das der typ verloren geht.

desweiteren kann man ja auch ein anderes objekt nach wahl nutzen und solange alle im objekt enthaltenen felder ISerializable implementieren; und das ist bei eig allen relevanten basis klassen und typen der fall, also brauch ich auch dann wieder keinen finger zu krümmen außer das ganze in nen formatter rein zu werfen
tolio is offline  
Old 10/04/2014, 19:12   #7



 
Shawak's Avatar
 
elite*gold: 0
The Black Market: 259/0/0
Join Date: Apr 2010
Posts: 10,291
Received Thanks: 3,611
@tolio: Die extra Lib welche das Json Format zu Verfügung stellt wird heutzutage sowieso in sehr vielen Projekten sowieso gebraucht, ansonsten sollte es auch möglich sein diese durch den JavaScriptSerializer zu ersetzen.

edit: Ist mir durchaus bewusst, allerdings ging es mir nicht casten zu müssen. Außerdem sollen damit ja auch nicht ganze Objekte sondern halt eben nur die statische Konfig Klasse serialisiert werden, dass es in .net serializable gibt sollte jedem klar sein.

@Mostey: Bei dieser Variante muss man wie bei vielen anderen Varianten casten und genau das wollte ich vermeiden, deswegen mein statisches Beispiel. Außerdem wird einem in der IDE nicht angezeigt welche Variablen gegeben sind und die Standartwerte gehen ohne weiteren Aufwand auch verloren. Natürlich ist meine Methode etwas langsamer, wodurch beide ihre Vor- und Nachteile haben. Im Endeffekt muss aber jeder selber entscheiden welche für ihn die geeignetere ist.

Lg
Shawak is offline  
Old 10/05/2014, 16:33   #8
 
elite*gold: 2
Join Date: May 2010
Posts: 846
Received Thanks: 3,938
Der BinaryFormatter ist in meinen Augen keine brauchbare Lösung. Wieso? Weil er auch Assembly Daten speichert und du entsprechend die Datei nicht mehr laden kannst wenn deine Assembly eine andere Version hat, außerdem finde ich dass Konfigurationsdateien immer in einer lesbaren Text-Form gespeichert werden sollten.
Am besten Xml oder Json, ob man jetzt dafür das .Net Framework oder third-party libraries nutzt ist hier doch latte.

Zu dem Snippet: Ich würde eher einen ConfigManager basteln der die Config-Instanzen managed anstatt die Config Klasse selber statisch zu machen. Damit sparst du dir diese unnötigen Reflection-Methoden.
-PinkiWinki- is offline  
Thanks
1 User
Old 10/05/2014, 19:39   #9
 
tolio's Avatar
 
elite*gold: 2932
The Black Market: 169/1/0
Join Date: Oct 2009
Posts: 6,966
Received Thanks: 1,097
Quote:
Originally Posted by -PinkiWinki- View Post
Der BinaryFormatter ist in meinen Augen keine brauchbare Lösung. Wieso? Weil er auch Assembly Daten speichert und du entsprechend die Datei nicht mehr laden kannst wenn deine Assembly eine andere Version hat
das ist kein problem, geht zb mit:
+
Simple
oder


Quote:
Originally Posted by -PinkiWinki- View Post
außerdem finde ich dass Konfigurationsdateien immer in einer lesbaren Text-Form gespeichert werden sollten.
sehe ich keinen grund für
tolio is offline  
Old 10/05/2014, 20:31   #10



 
Shawak's Avatar
 
elite*gold: 0
The Black Market: 259/0/0
Join Date: Apr 2010
Posts: 10,291
Received Thanks: 3,611
Quote:
Originally Posted by tolio View Post

sehe ich keinen grund für
Genau darum soll es in diesem Beispiel aber gehen.
Shawak is offline  
Old 10/12/2014, 00:25   #11


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
Quote:
Originally Posted by -PinkiWinki- View Post
Der BinaryFormatter ist in meinen Augen keine brauchbare Lösung. Wieso? Weil er auch Assembly Daten speichert und du entsprechend die Datei nicht mehr laden kannst wenn deine Assembly eine andere Version hat, außerdem finde ich dass Konfigurationsdateien immer in einer lesbaren Text-Form gespeichert werden sollten.
Am besten Xml oder Json, ob man jetzt dafür das .Net Framework oder third-party libraries nutzt ist hier doch latte.

Zu dem Snippet: Ich würde eher einen ConfigManager basteln der die Config-Instanzen managed anstatt die Config Klasse selber statisch zu machen. Damit sparst du dir diese unnötigen Reflection-Methoden.
+ Defaultwerte sind bei Serialisierung so ne Sache.
Sofern der verwendete Serializer den Konstruktor ignoriert, werden in der Datei nicht vorhandene Settings mit dem Default Wert des Propertys belegt, was in vielen Fällen null ist - worauf ich für meinen Teil nicht bei jedem Setting testen möchte.
Und teils spucken übrigens auch einige Xml Serializer sehr hässliches Xml aus.

Eine eigene Klasse, die sich um das Parsen der Datei und Aufbauen eines Objekts kümmert, hat konsequenterweise den Vorteil, dass man mehr Kontrolle über Dateiformat und Aufbau des Objekts hat.

Der ConfigManager Ansatz hat im Vergleich zur statischen Setting Klasse auch den Vorteil, dass man leicht Unterstützung für verschiedene Profile einbauen kann.

Ich glaube, ich sollte mal meine kleine Settinglib hier posten :x

Quote:
sehe ich keinen grund für
Und dann ist mal ein Fehler im Programm und/oder inkonsistente Settings werden erzeugt und der Nutzer hat Pech gehabt?
Na super.
MrSm!th is offline  
Reply


Similar Threads Similar Threads
suche class config
12/18/2011 - WoW Bots - 0 Replies
suche class config 3.3.5a vom Krieger für den GPBot. Wenn falsche section bitte moven.
[Problem]Rogue Class config
06/08/2010 - WoW Bots - 3 Replies
heyho Also hab die Rogue class config so bearbeitet das auf N4 Gouge ist und auf N% Slice and Dice nun ist mein problem der bot benutz die attacken irgendwie nicht. Greeez Neo



All times are GMT +2. The time now is 05:39.


Powered by vBulletin®
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2024 elitepvpers All Rights Reserved.