How to implement the Singleton class for defining system variables? - c#

I am trying to implement the Singleton Pattern.
Here is what I have done so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
namespace POS
{
public sealed class Settings
{
private static Settings instance = null;
private static readonly object padlock = new object();
//System Variables
public string SYSTEM_NAME { get; set; }
public Settings()
{
//start new connection to the database
dbConnetion db = new dbConnetion();
string sql = " SELECT system_name "
+ " FROM configuration "
+ " LIMIT 1";
//read the system variable
foreach (var i in db.getData(sql, null, r =>
new globalSettings()
{
_sys_name = r["system_name"].ToString()
}
)
)
{
SYSTEM_NAME = i._sys_name;
}
}
public static Settings Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Settings();
}
return instance;
}
}
}
}
class globalSettings
{
public string _sys_name;
}
}
And when I want to read the variable I do this:
GlobalName.Text = Settings.SYSTEM_NAME;
but this is not working.
I get the following error:
Error 1 An object reference is required for the non-static field, method, or property 'POS.Settings.SYSTEM_NAME.get'
How can I read the variables correctly? also did I manage to implement the Singleton pattern correctly?

In your code, you want:
GlobalName.Text = Settings.Instance.SYSTEM_NAME;
this will instantiate the singleton if it doesn't exist, and allow you to use its instance (stored in the Instance static property).
For storing such properties there is an easier pattern that can be used in C#:
public static class Settings
{
public static string SystemName { get; set; }
public const string SomeOtherProperty = "x";
public static int AnotherOne
{
get
{
return 42;
}
}
}
Be warned however that such global objects introduce a hidden dependency, making your code harder to maintain (changes in one place may affect distant, non-obvious places in code. - less apparent if all properties are constants though) and harder to test (you can't stub/mock a singleton).
To make your implementation a bit cleaner:
Your class violates the Single Responsibility Principle: you should separate reading the configuration from DB from the object that simply aggregates it.
Make the dependency on the configuration explicit. For example, each class that needs the configuration should accept its instance in the constructor and use it for its purposes. This way you can also easily test such class, providing different configurations and testing behaviour for different settings.
Then you can test your classes without using the database, but using some hardcoded settings. Imagine also, that you may want to read the settings from a file or a command line sometimes.

Related

Optimal way of saving application configuration in C#

I have a Configuration class that stores certain variables which serve as settings. And I'm struggling to find easiest and most optimal way to save it to file - would be weird if user had to configure it every time.
Example class:
public static Configuration
{
public static bool A = false;
public static bool B = false;
public static int C = 100;
}
Serializing collection is not an issue, but i cannot really make collection out of these variables, since they have not matching data types.
I'm certain solution is simple, but for some reason I'm stuck here.
Elaborating on my comment, you're better off converting your static class into an instance class for minimizing manual coding to store/read the property values in the future. This refactoring can be done in minutes. So do that as a first step, it shouldn't take too long to do, and a simple "Find/Replace" can fix all of your declarations everywhere in your code where you previously used "Configuration".
Keep your implementation static, but change to a single instance that you are accessing.
public class Configuration
{
private static Configuration instance;
public static Configuration Instance
{
get
{
if (instance == null)
{
instance = new Configuration();
}
return instance;
}
set
{
instance = value;
}
}
public bool A { get; set; }
public bool B { get; set; }
public int C { get; set; }
}
Do a Find/Replace where ever you declared your static class and replace "Configuration." with "Configuration.Instance.". Also, where you previously declared static properties like public static bool A; public static bool B; ... just select all of the text, do a Find/Replace and replace "static " with "".
Save/Read your data
// To Save
File.WriteAllText(#"c:\temp\myconfig.json", Newtonsoft.Json.JsonConvert.SerializeObject(Configuration.Instance));
// To Read
using (var file = File.OpenText(#"c:\temp\myconfig.json"))
{
JsonSerializer serializer = new JsonSerializer();
Configuration.Instance = (Configuration)serializer.Deserialize(file, typeof(Configuration));
}

Is there a way for a getter in C# to cache its result in-line?

I've been working on a Discord bot and one of my abstract classes that represents servers ("Bot Contexts") contains the following data.
public virtual Command[] ContextSpecificCommands { get; } = null;
In user-defined Contexts I expect them to override this (if the server that has this code needs to). There's an issue, however, which is that I expect Commands to be singletons in the scope of a Context. This means that CommandFoo can exist only once in CoolContextNumberOne, and can also exist in CoolContextNumberTwo (as a separate instance of CommandFoo), but a single context cannot have two instances of CommandFoo in it.
My issue comes in with the behavior of getters. If the user does this...
public override Command[] ContextSpecificCommands => new Command[] {
new CommandFoo()
};
Then this will instantiate CommandFoo every time ContextSpecificCommands is referenced.
Is there any way to ensure that ContextSpecificCommands is cached in-line so that it only instantiates that container array once? I'd like to avoid requiring the user to specify a field and point to that field if possible.
This code was for the intellectual exercise, it is not recommended!
If you are willing to force the implementors of your BotContexts to use a specific form, then you can insert a type of singleton pattern into the property definition.
Consider:
public static class Singleton {
public static T For<T>(Func<T> makeSingleton) => Singleton<T>.For(makeSingleton);
}
public static class Singleton<T> {
static Dictionary<Func<T>, T> Cache = new Dictionary<Func<T>, T>();
public static T For(Func<T> makeSingleton) {
T singleton;
if (!Cache.TryGetValue(makeSingleton, out singleton)) {
singleton = makeSingleton();
Cache[makeSingleton] = singleton;
}
return singleton;
}
}
Now you can use this like so:
public class CoolContextNumberOne : BotContexts {
public override Command[] ContextSpecificCommands => Singleton.For(() => new Command[] { new CommandFoo() });
}
public class CoolContextNumberTwo : BotContexts {
public override Command[] ContextSpecificCommands => Singleton.For(() => new Command[] { new CommandFoo() });
}
Each CoolContext will create one instance of CommandFoo regardless of how many times ContextSpecificCommands is called.
Since in C# the use of a new expression will always generate a new object, it is difficult (impossible?) to see how you could have the code the same and figure out when to generate a new object and when to return an existing object (e.g. if a Command was actually a proxy object). If you didn't mind a dependency on optimization being enabled, StackFrame and GetILOffset could help, but would probably fail in debug mode. And be very brittle.
It may be possible to hide the use of Singleton in the types of Commands by using dynamic and Expando but that seems like an even worse idea.
This is not natively possible without adding extra code.
In order for a result to cache, a separate backing field must be created and the code must be set up to work with this field.
In order to resolve my dilemma, I have altered my code from:
// User will override this.
public virtual Command[] ContextSpecificCommands { get; } = null;
To:
// User will override this.
protected virtual Command[] ContextSpecificCommands { get; } = null;
// These control the cache.
private bool HasPopulatedCommandCache = false;
private Command[] CommandCache = null;
// Things will reference this to get ahold of commands.
public Command[] Commands {
get {
if (!HasPopulatedCommandCache) {
HasPopulatedCommandCache = true;
CommandCache = ContextSpecificCommands;
}
return CommandCache;
}
}
This allows the code to meet all of the goals specified in my original question. The user's class can use an in-line expression to define their commands without the worry of this array being instantiated every time it is referenced.

HowTo: Return an object from a (static) method?

I'm building a WinForms application using C# 2.0 for a Job Scheduler.
Wrote a public class Job in Program.cs defining the Job object.
//Class for defining Job object and its properties
public class Job
{
private int IntJobID;
public int JobID
{
get {return IntJobID;}
set {IntJobID = value;}
}
private string StrJobName;
public string JobName
{
get { return StrJobName; }
set { StrJobName = value; }
}
//Several other properties defined here.
}
Also wrote a public static class ApplicationName in Program.cs for containing application-wide config variables and all helper methods.
//Static Class for Global Properties and Global Methods
//*****************************************************
public static class ApplicationName
{
//Global Properties
//***************************
public static string ConfigFilePath = "D:\\ApplicationName\\conf\\ApplicationName.ini";
public static string DBFilePath = "D:\\ApplicationName\\data\\ApplicationName.xml";
//Global Methods
//************************
public static void HelperMethod1(Args)
{
}
public static string HelperMethod2(Args)
{
}
public static Job GetJobByID(int JobID)
{
XmlDocument XMLDB = new XmlDocument(); XMLDB.Load(DBFilePath);
Job ObjJob = new Job();
ObjJob.JobName = XMLDB.SelectSingleNode("/ApplicationName/Job[JobID=" + JobID.ToString() + "]/JobName").InnerText.Trim();
//Several other properties are retrieved from the DB and set to the object here.
return ObjJob;
}
}
One of the helper methods GetJobByID in the public static class ApplicationName is required to create/instantiate a Job object and return the same. I believe this is possible, a method within ClassA creating and returning an instance/object of ClassB.
Note: This method is meant for access from other forms such as Form1.cs, Form2.cs, etc. in the following way. To my knowledge, this is also allowed and is accepted practice.
private void FormAddEditJob_Load(object sender, EventArgs e)
{
int SelectedJobID = Convert.ToInt32(this.Tag);
//Creating an instance of the Job Class
//Assigning the value of the Job object returned by GetJobByID method
Job JobToEdit = ApplicationName.GetJobByID(SelectedJobID);
TextBoxJobID.Text = SelectedJobID.ToString();
TextBoxJobName.Text = JobToEdit.JobName;
}
PROBLEM: The object returned by GetJobByID method is not getting stored in the object reference JobToEdit. Or even possible that the GetJobByID method does not return an object appropriately / as expected. What am I doing wrong here? Is this not the right way to return an object?
Issue identified and resolved.
One of the statements ObjJob.PropertyName = XMLDB.SelectSingleNode() in the GetJobByID method was throwing an exception, due to fetching null values from the DB, thereby resulting in the ObjJob object being returned as null. Found this by debugging line by line.

How to use Global Variables in C#?

How do I declare a variable so that every class (*.cs) can access its content, without an instance reference?
In C# you cannot define true global variables (in the sense that they don't belong to any class).
This being said, the simplest approach that I know to mimic this feature consists in using a static class, as follows:
public static class Globals
{
public const Int32 BUFFER_SIZE = 512; // Unmodifiable
public static String FILE_NAME = "Output.txt"; // Modifiable
public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}
You can then retrieve the defined values anywhere in your code (provided it's part of the same namespace):
String code = Globals.CODE_PREFIX + value.ToString();
In order to deal with different namespaces, you can either:
declare the Globals class without including it into a specific namespace (so that it will be placed in the global application namespace);
insert the proper using directive for retrieving the variables from another namespace.
You can have static members if you want:
public static class MyStaticValues
{
public static bool MyStaticBool {get;set;}
}
First examine if you really need a global variable instead using it blatantly without consideration to your software architecture.
Let's assuming it passes the test. Depending on usage, Globals can be hard to debug with race conditions and many other "bad things", it's best to approach them from an angle where you're prepared to handle such bad things. So,
Wrap all such Global variables into a single static class (for manageability).
Have Properties instead of fields(='variables'). This way you have some mechanisms to address any issues with concurrent writes to Globals in the future.
The basic outline for such a class would be:
public class Globals
{
private static bool _expired;
public static bool Expired
{
get
{
// Reads are usually simple
return _expired;
}
set
{
// You can add logic here for race conditions,
// or other measurements
_expired = value;
}
}
// Perhaps extend this to have Read-Modify-Write static methods
// for data integrity during concurrency? Situational.
}
Usage from other classes (within same namespace)
// Read
bool areWeAlive = Globals.Expired;
// Write
// past deadline
Globals.Expired = true;
A useful feature for this is using static
As others have said, you have to create a class for your globals:
public static class Globals {
public const float PI = 3.14;
}
But you can import it like this in order to no longer write the class name in front of its static properties:
using static Globals;
[...]
Console.WriteLine("Pi is " + PI);

Following the DRY principle in ASP.NET

I have just recently got involved in a classic ASP.NET project which contains lots of storing and reading values from the session and query strings. This could look something like the following:
Session["someKey"]=someValue;
And somewhere else in the code the value in the session is read. Clearly this violates the DRY principle since you'll have the literal string key spread out all over the code. One way to avoid this could be to store all keys as constants that could be referenced everywhere there is a need to read and write to the session. But I'm not sure that's the best way to do it. How would you recommend I best handle this so that I don't violate the DRY principle?
Create a separate public class where you can define your constants, e.g
public class SessionVars
{
public const string SOME_KEY = "someKey";
public const string SOME_OTHER_KEY = "someOtherKey";
}
and then anywhere in your code you can access session variables like this:
Session[SessionVars.SOME_KEY]=someValue;
This way you can get IntelliSence and other bells and whistles.
I think you're reading too much into DRY. I pertains more to things that could be wrapped up in a function. I.e. instead of repeating the same fives lines all over the place wrap those 5 lines in a function and call the function everywhere you need it.
What you have as an example is just setting a value in a dictionary (the session object in this case), and that is the simplest way to store and retrieve objects in it.
I can't remember for the life of me where I humbly re-purposed this code from, but it's pretty nice:
using System;
using System.Web;
namespace Project.Web.UI.Domain
{
public abstract class SessionBase<T> where T : class, new()
{
private static readonly Object _padlock = new Object();
private static string Key
{
get { return typeof(SessionBase<T>).FullName; }
}
public static T Current
{
get
{
var instance = HttpContext.Current.Session[Key] as T;
lock (SessionBase<T>._padlock)
{
if (instance == null)
{
HttpContext.Current.Session[Key]
= instance
= new T();
}
}
return instance;
}
}
public static void Clear()
{
var instance = HttpContext.Current.Session[Key] as T;
if (instance != null)
{
lock (SessionBase<T>._padlock)
{
HttpContext.Current.Session[Key] = null;
}
}
}
}
}
The idea behind it two fold. The type created should be the only type you need. It's basically a big strongly-typed wrapper. So you have some object you want to keep extending information in:
public class MyClass
{
public MyClass()
public string Blah1 { get; set; }
}
Then down the road you extend MyClass and you don't want to have to remember all the Key Values, store them in AppSettings or Const variables in Static Classes. You simply define what you want to store:
public class MyClassSession : SessionBase<MyClass>
{
}
And anywhere in your program you simply use the class.
// Any Asp.Net method (webforms or mvc)
public void SetValueMethod()
{
MyClassSesssion.Current.Blah1 = "asdf";
}
public string GetValueMethod()
{
return MyClassSession.Current.Blah1;
}
Optionally you could place the access to this session object in a base page and wrap it in a property:
class BasePage : Page
{
...
public string MySessionObject
{
get
{
if(Session["myKey"] == null)
return string.Empty;
return Session["myKey"].ToString();
}
set
{
Session["myKey"] = value;
}
}
...
}
Here you are repeating the myKey string but it is encapsulated into the property. If you want to go to the extreme of avoiding this, create a constant with the key and replace the string.

Categories

Resources