|
You last visited: Today at 05:39
Advertisement
[C#] Dynamic Config Class
Discussion on [C#] Dynamic Config Class within the Coding Snippets forum part of the Coding Releases category.
10/01/2014, 11:27
|
#1
|
elite*gold: 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:
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:
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
|
|
|
10/04/2014, 06:37
|
#2
|
elite*gold: 2932
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
|
|
|
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
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.
|
|
|
10/04/2014, 15:54
|
#4
|
elite*gold: 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.
|
|
|
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
@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);
}
|
|
|
10/04/2014, 19:06
|
#6
|
elite*gold: 2932
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
|
|
|
10/04/2014, 19:12
|
#7
|
elite*gold: 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
|
|
|
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.
|
|
|
10/05/2014, 19:39
|
#9
|
elite*gold: 2932
Join Date: Oct 2009
Posts: 6,966
Received Thanks: 1,097
|
Quote:
Originally Posted by -PinkiWinki-
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-
außerdem finde ich dass Konfigurationsdateien immer in einer lesbaren Text-Form gespeichert werden sollten.
|
sehe ich keinen grund für
|
|
|
10/05/2014, 20:31
|
#10
|
elite*gold: 0
Join Date: Apr 2010
Posts: 10,291
Received Thanks: 3,611
|
Quote:
Originally Posted by tolio
sehe ich keinen grund für
|
Genau darum soll es in diesem Beispiel aber gehen.
|
|
|
10/12/2014, 00:25
|
#11
|
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,904
Received Thanks: 25,394
|
Quote:
Originally Posted by -PinkiWinki-
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.
|
|
|
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.
|
|