I started writing a new framework in C# which can be used for any server development. It contains the basic stuff, such as database, TCP and configuration. I did write the configuration last night and I would love to get some constructive criticism and tips on it.
I know I didn't document the code yet, planning on doing it once I'm 100% happy with it.
First off, we have the BaseConfiguration
class. This class is basically the base (superclass) of all configuration modules.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
namespace AuroraFramework.Configuration
{
public abstract class BaseConfiguration
{
private readonly string filePath;
private JObject jsonSettings;
protected BaseConfiguration(string filePath)
{
this.filePath = filePath;
ReadFile();
}
private void ReadFile()
{
StreamReader reader = new StreamReader(filePath);
jsonSettings = JsonConvert.DeserializeObject<JObject>(reader.ReadToEnd());
}
protected T Get<T>(string key)
{
return jsonSettings[key].Value<T>();
}
}
}
What it does is simple. It reads the file you pass down in the constructor, and 'converts' it into a JObject
. That JObject
is used to get values from. Then the Get
function is used to get values from the JObject
and return it in the right datatype. The reason I chose for this is to have more control than when I use JsonConvert.DeserializeObject<TYPE>(string)
.
The whole class is used to it's easy to implement new configuration modules without reading the whole file on your own and without writing much code.
Next, we have the DatabaseConfiguration
class, which is simply one of the configuration modules in the framework.
namespace AuroraFramework.Configuration.Types
{
public class DatabaseConfiguration : BaseConfiguration
{
public string Server { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Database { get; set; }
public DatabaseConfiguration()
: base("db.settings.json")
{
Server = Get<string>("server");
Username = Get<string>("username");
Password = Get<string>("password");
Database = Get<string>("database");
}
}
}
This simply uses the BaseConfiguration
class as superclass. This will let the superclass read the file and convert it to a JObject
. The only thing for the configuration module itself to do is call the Get
function on every property.
And then, you use DatabaseConfiguration dbConfig = new DatabaseConfiguration()
in the framework and pass it down to the classes that need to use the configuration.
1 Answer 1
Do you really want the properties of DatabaseConfiguration
to be settable?
public string Server { get; set; }
If time is not an issue, I would make the call of each property "lazy":
public string Server => Get<string>("server");
-
\$\begingroup\$ Oh, I completely forgot! Yeah, you're right. And what do you mean with
if time is not an issue
? \$\endgroup\$Navine– Navine2018年06月02日 10:51:08 +00:00Commented Jun 2, 2018 at 10:51 -
\$\begingroup\$ @Navine: I just mean the time it takes to read the property from the JObject each time for instance the
Server
property is called. BTW with "lazy" I probably mean "on demand". \$\endgroup\$user73941– user739412018年06月02日 10:55:30 +00:00Commented Jun 2, 2018 at 10:55 -
\$\begingroup\$ Oh I get it, you mean it's called when you call the property? (just to see if I understand) Doesn't that mean it will always call that? I don't think it's much of an issue as it shouldn't really take that long and aren't called much. \$\endgroup\$Navine– Navine2018年06月02日 11:28:30 +00:00Commented Jun 2, 2018 at 11:28