[英]Life of a Static class in ASP.Net
In my UI layer, I store some timezone information in the Session State. 在我的UI层中,我将一些时区信息存储在会话状态中。
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. 在我的UI层中,我向下传递已登录用户的UserID,并且数据库中存储了该用户的时区信息。 I would prefer not to pass the Timezone down WITH the user ID. 我希望不要将时区与用户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
. 那可能会返回一个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. 然后,如果CurrentDate == null,则使用UserId从该用户的数据库中获取TimeZoneId-因此,数据库调用只会发生一次,并且只有在之前从未发生过时才会发生。
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? 还是在Asp.Net应用程序运行时? 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: 它使用EF代码优先方法,因此,如果不使用EF,则应该对其进行调整:
Edit 2: This is how you should use it: 编辑2:这是您应如何使用它:
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 . 编辑:派生自ASP安全工具包 。
From my experience it goes like this. 根据我的经验,它是这样的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.