Problem
I have so many classes like this in my solution but I’ve chosen this one just to show you guys what I mean by it.
In my solution I have lots of classes that just follow the same 2 classes exactly the same, except for the class name and for different purposes.
The issue is, I think I’m OP’ing it. Does something this simple, something I do with around 50 class pairs in my solution really need to take up 2 files and this much code?
It seems like it can be improved but I just can’t work out a well-driven way, someone said something about structs but I didn’t really look into it too much and it’s been too long to remember what else they said.
Is there some sort of layout or structure I can do to reduce the amount of code or the time it takes to code this? I feel like somethings staring me right in the face and I’m missing it.
The purpose of this class pair is to cache database information, store it in a dictionary and return it in case you need it later. It saves an extra call to the database every time I need to get something, and it’s just a lot easier to maintain and work with than constant database calls all over the place.
internal class SubscriptionHandler
{
private readonly Dictionary<int, Subscription> _subscriptions;
public SubscriptionHandler()
{
_subscriptions = new Dictionary<int, Subscription>();
}
public void Load()
{
using (var dbConnection = Program.Server.DatabaseHandler.Connection)
{
dbConnection.SetQuery("SELECT * FROM `subscriptions`;");
using (var reader = dbConnection.ExecuteReader())
{
while (reader.Read())
{
var subscriptionId = reader.GetInt32("id");
_subscriptions[subscriptionId] = new Subscription();
}
}
}
}
public bool TryGetSubscriptionById(int subscriptionId, out Subscription subscription)
{
return _subscriptions.TryGetValue(subscriptionId, out subscription);
}
}
internal class Subscription
{
public int Id;
public string Name;
public string Badge;
public int Credits;
public int Pixels;
public int Respects;
public Subscription(int id, string name, string badge, int credits, int pixels, int respects)
{
Id = id;
Name = name;
Badge = badge;
Credits = credits;
Pixels = pixels;
Respects = respects;
}
}
Solution
So you’re saying that you have a bunch of classes representing db rows, and need a WhateverHandler
for each class?
Use generics.
https://msdn.microsoft.com/en-us/library/ms172192(v=vs.110).aspx
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/
The type is replaced whenever you need to use it, like so:
internal class Handler<T> where T : new()
{
private readonly Dictionary<int, T> _rows;
private readonly string _tableName;
private Handler() {}
public Handler(string tableName)
{
_rows = new Dictionary<int, T>();
_tableName = tableName;
}
public void Load()
{
using (var dbConnection = Program.Server.DatabaseHandler.Connection)
{
dbConnection.SetQuery("SELECT * FROM `{0}`;".Format(tablename));
using (var reader = dbConnection.ExecuteReader())
{
while (reader.Read())
{
var rowId = reader.GetInt32("id");
_rows[rowId] = new T();
}
}
}
}
public bool TryGetById(int rowId, out T row)
{
return _rows.TryGetValue(rowId, out row);
}
}
edit: thanks @kuskmen for reminding me about the new()
constraint