简体   繁体   中英

Life of a Static class in ASP.Net

In my UI layer, I store some timezone information in the Session State.

I now need access to the timezone in my Service/Business/Data layers.

From my UI layer, I pass down the UserID of the logged on user, and my database has the Timezone information stored for that user. I would prefer not to pass the Timezone down WITH the user ID.

The Timezone is only used on a few calls where time is important. (Has a project started, is a person on leave today.. etc).

I m thinking of maybe having a Static class, which is referenced on all layers (Service/Business/Data), which has a field for the Timezone info. I'd like it to be static, so that I can reference it:

var CurrentDate = CommonClass.GetLocatDateTime(_userId);

That would maybe return a DateTime .

And then, if CurrentDate == null, using the UserId, go get the TimeZoneId from the database for that user - so, the database call will only happen once, and only happen if it hadn't happened before.

But, when is the static class 'born' and 'killed'?

Is it per session of a user? Or is it while the Asp.Net application is running? When I say, a user session, I mean, each time the user clicks something, is a new session created, and therefore, my static class will be created then? Or is the Static class 'visible' to all other sessions? I want it to be limited to the current user.

But, when is the static class 'born' and 'killed'?

You don't need a reference of the class in order to access a static member. So there's never a birth or a death.

Is it per session of a user?

No, it is global for your entire application and shared between all users.

I want it to be limited to the current user.

Then forget about static members and use the session.

Static class members are shared between user sessions. However, I don't see any possible issues with static methods . As long as you don't store a shared (static) state (=you don't use static fields/properties) you are safe.

Static is equivalent to singleton – common for the entire application thus all users. You need session-based approach to achieve this. However, if you don't have access to session (such as in business libraries), you can use singleton approach (code example to follow.)

Edit: code example to achieve this with singleton approach (similar to static but more maintainable). It uses EF code first approach so you should adapt it if you don't use EF:

Edit 2: This is how you should use it:

To get time in user timezone:

var userId = 5; // assuming 5 a valid user. If not found, current local timezone will be used (`DateTime.Now`)
var localTime = UserDateTime.Instance.GetTime(userId);`

If a new user is added or existing is modified, you can re-load timezones: (you can optimize it further as per your needs.)

UserDateTime.Instance.LoadTimezones();

Implementation:

namespace YourApp
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Data.Entity;

    class UserDateTime
    {
        public static readonly UserDateTime Instance = new UserDateTime();

        private UserDateTime() // singleton
        {
            LoadTimezones();
        }

        private Dictionary<int, string> _userTimezones = new Dictionary<int, string>();
        public DateTime GetTime(int userId)
        {
            if (_userTimezones.ContainsKey(userId))
                return TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById(_userTimezones[userId]));
            else
                return DateTime.Now; // You could throw an error.
        }


        public void LoadTimezones()
        {
            using (var db = new YourDbContext())
            {
                _userTimezones = db.UserTimezones.ToDictionary(t => t.UserId, t => t.TimezoneId);
            }
        }
    }


    class UserTimezone
    {
        public int UserId { get; set; }
        public string TimezoneId { get; set; }
    }

    class YourDbContext : DbContext
    {
        public DbSet<UserTimezone> UserTimezones { get; set; }
    }
}

Edit: Derived from ASP Security Kit .

From my experience it goes like this.

  • A user hits the website.
  • The site starts up
  • If a static class is called - its static constructor will be invoked and the static class will be 'born'
  • The user finishes his session
  • The app and the static class stays alive and well
  • Another user hits the website and accesses the static class
    • The static class' constructor is not called because the static class has allready been 'born' and accessing any of its static variables will be the same as the previous user left them
  • No one else hits the website for longer than the timeout period (usually set to about 10 mins on iis)
  • The website closes down and the static class is disposed, and the next user will start all over again

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM