ijaz noufal
ijaz noufal

Reputation: 11

How to have a singleton class and use it through out the application c#

I have a class which deserializes a JSON file. The JSON is styleconfig.json

    {  
        "Style1": {  
            "Font":       "Arial",   
            "width":      "25px",   
            "className":    "Grid-side"
        }  ,
"Style2": {  
            "Font":       "Arial",   
            "width":      "25px",   
            "className":    "Grid-side"
        }  
    }  

I have a classA:

 var jss = new JavaScriptSerializer();
string json = new StreamReader(context.Request.InputStream).ReadToEnd();
Dictionary<string, string> sData = jss.Deserialize<Dictionary<string, string>>(json);

So I need to call this classA every time in my application For Example There are two pages...Page1 and page2 both the style variables are there on json so every time I need to call the classA to Deserialize

  1. page1 call classA to Deserialize
  2. page2 call classA to Deserialize

So this may affect the performance.End of the day the JSON file is the same for the whole application

So my requirement is to run classA only once when I login into the application and make the Deserialized JSON object throughout the application. I need some help with this

Upvotes: 1

Views: 769

Answers (3)

Amo Robb
Amo Robb

Reputation: 850

If I have correctly understood your question, apart from a lazy field already explained in other comments, have you tried a simple property?

 public class ClassA
    {
        //Just a singleton model
        static ClassA _SingleInstance = null;
        public static ClassA SingleInstance
        {
            get
            {
                if (_SingleInstance == null)
                    _SingleInstance = new ClassA();

                return _SingleInstance;
            }
        }

        Dictionary<string, string> _Data = null;
        public Dictionary<string, string> Data
        {
            get
            {
                if (_Data == null)
                    LoadData();
                return _Data;
            }
        }

      
        private ClassA()
        {
            //your constructor
        }
        
        //As pointed out by torvin, to avoid multithread races, load must
        //be synchronized
        private void LoadData()
        {
            lock(LoadMutex)
            {
                if (_Data == null)
                {
                    var jss = new JavaScriptSerializer();
                    string json = new StreamReader(context.Request.InputStream).ReadToEnd();
                    _Data = jss.Deserialize<Dictionary<string, string>>(json);
                }
            }
        }

        private static readonly object LoadMutex = new object();

    }

and then from Page1 and Page2, you call it:


    Dictionary<string, string> myConfigData = ClassA.SingleInstance.Data;

Upvotes: 0

Steve Harris
Steve Harris

Reputation: 5109

You could do this with a static class and use a Lazy<> to ensure it is loaded only once:

public static class A
{
    private static Lazy<Dictionary<string, string>> _data = new Lazy<Dictionary<string, string>>(() => GetData());

    public static Dictionary<string, string> Data => _data.Value;

    private static Dictionary<string, string> GetData()
    {
        var jss = new JavaScriptSerializer();
        string json = new StreamReader(context.Request.InputStream).ReadToEnd();
        return jss.Deserialize<Dictionary<string, string>>(json);
    }
}

Upvotes: 1

torvin
torvin

Reputation: 7101

You should use Lazy<T> for that. Here's an example:

static class ClassA 
{
    private static Lazy<Dictionary<string, string>> _json = new Lazy<Dictionary<string, string>>(ReadJson);

    private static Dictionary<string, string> ReadJson()
    {
        var jss = new JavaScriptSerializer();
        var json = new StreamReader(context.Request.InputStream).ReadToEnd();
        return jss.Deserialize<Dictionary<string, string>>(json);
    }

    public Dictionary<string, string> Json => _json.Value;

}

Now the first time you read ClassA.Json the file will be parsed and read. The subsequent calls will just return the cached value.

Upvotes: 0

Related Questions