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.
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.