0

I have the next static class:

public static class GlobalVar
{
    public static string DatabaseName = "ProjectDatabase.mdf";

    public static AdminClass Admin;

    public static string TruePath = AppDomain.CurrentDomain.BaseDirectory;

    public static string TimeStampPattern = "dd/MM/yyyy HH:mm";

    static GlobalVar()
    {
        TruePath = TruePath.Remove(TruePath.Length - 1);
        Admin = new AdminClass("Admin", "Admin");
        GlobalStatus = new Dictionary<string, string>();
        string Query = "SELECT * FROM global_status";
        DataTable Types = MyAdoHelper.ExecuteDataTable(GlobalVar.DatabaseName, Query);
        foreach (DataRow Status in Types.Rows)
        {
            GlobalStatus.Add(Status["title"].ToString(), Status["info"].ToString());
        }
    }

    public static Dictionary<string, string> GlobalStatus; 

    public static string BasePath = HttpContext.Current.Request.ApplicationPath;
}

The GlobalStatus is a dictionary receives the custom errors the site may return. When I launch the project (Microsoft Visual Web developer 2008), it gives an error:

Object reference not set to an instance of an object.

when trying to get a value from GlobalStatus (eg. GlobalVar.GlobalStatus["Page_NoAccess"]).

Only after a minute, when I launch the project again, it runs fine.

How can I fix this, like force it the browser to wait until it fills GlobalStatus. I need this class to initialize only once, since it contains global variables which I don't want to be recalled every browser request.

Thanks

Novak
  • 2,760
  • 9
  • 42
  • 63
  • 2
    add the stack trace and the specific code that you get that exception at – eyossi Jun 10 '12 at 18:43
  • If think TruePath or BasePath could be the null values you are looking for. – Grumsh Jun 10 '12 at 18:47
  • Thing is, that it happens once in a while. If I will reset my PC, and run the project it can run fine. It happens once in a while so recreating the exception can take some time. – Novak Jun 10 '12 at 18:54
  • Did you manage to reproduce it in a console app? Did you try to shave off some code to try and isolate the problem? Much of the code you pasted is not relevant to the problem you are facing. – Vitaliy Jun 10 '12 at 18:59
  • Is there a possibility that it's caused by the delay until the static class connects the database to call for the values? Maybe there is another way of creating this dictionary? *Not with a static class – Novak Jun 10 '12 at 19:10

1 Answers1

2

First of all, I want to suggest you global vars concept in an object-oriented code is a bad idea.

In order to solve your problem, you need to use built-in, out-of-the-box ASP.NET approaches: global application class.

Use Application_Start event handler and invoke initialization processes during this event .

Anything opposed to above statement is a bad idea.

Now... how to do it better

  1. For everything that you find that are settings use AppSettings or settings files.
  2. Using static constructors for application initialization is a bad idea. Create a static class with static methods like Initialize(), Start().... Call them in Application_Start event of global application class.
  3. Static classes with static fields and data in a multi-threaded environment like ASP.NET are a big fail. More than a thread can initialize your application at once. How your code manages this situation?.
  4. Forget global variables concept in an object-oriented piece of software. Use settings (like I said in 1st point) or create constants or fields (static or instance ones) as part of the class that's going to consume it.

UPDATE & NOTE I suggest this MSDN article about static constructors in order to understand why these are a bad idea in ASP.NET initialization.

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • Thank you for helping, I will now start building it. Again, Much thanks! – Novak Jun 10 '12 at 19:16
  • 1
    Static constructors are the BEST way of initialising a singleton, which is a perfectly valid design pattern, especially in a multi-threaded environment. .Net ensures static constructors are called once & once only. I suspect that's why you got down voted. Your advice for the OP is sound though. – Simon Halsey Jun 10 '12 at 21:15
  • @SimonHalsey But I guess downvoter isn't familiar with ASP.NET. And sure, this is the best way for singletons, but OP code isn't a singleton. And again, how many times ASP.NET calls _Application_Start_ during application's life cycle? Once. And the most important part, _when_ static constructor is called? From MSDN: **A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.**. Now again, in ASP.NET, what's better? :) – Matías Fidemraizer Jun 11 '12 at 05:54
  • @SimonHalsey And, at the end of the day, I'd be wrong with following your statement of "static constructor are the best way of initializing a singleton". Why? If you want to initialize ALL resources for an application during its startup, it'll be better to do that at this point and avoid a lazy-loading. – Matías Fidemraizer Jun 11 '12 at 06:02
  • You misunderstand. Your advice is good. Initialise some other way. My point was IF you use a singleton pattern, in other circumstances, the best, thread safe way of initialising that class is via a static constructor. Singleton pattern is nothing to do with app initialisation. Your MSDN quote above is why static constructors work for singletons. – Simon Halsey Jun 13 '12 at 11:25
  • @SimonHalsey Ah, in that case, sorry for my misunderstanding! :) – Matías Fidemraizer Jun 13 '12 at 15:37