简体   繁体   English

ASP.Net中的静态类的寿命

[英]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. 根据我的经验,它是这样的。

  • 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) 没有其他人会超过超时时间(通常在iis上将其设置为大约10分钟)
  • The website closes down and the static class is disposed, and the next user will start all over again 网站关闭并且处置了静态类,下一个用户将重新开始

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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