簡體   English   中英

ASP.Net中的靜態類的壽命

[英]Life of a Static class in ASP.Net

在我的UI層中,我將一些時區信息存儲在會話狀態中。

現在,我需要訪問服務/業務/數據層中的時區。

在我的UI層中,我向下傳遞已登錄用戶的UserID,並且數據庫中存儲了該用戶的時區信息。 我希望不要將時區與用戶ID一起傳遞。

時區僅在時間很重要的幾個電話上使用。 (有一個項目開始了,今天有人休假。等)。

我在想可能有一個靜態類,該類在所有層(服務/業務/數據)上均被引用,該類具有用於時區信息的字段。 我希望它是靜態的,以便我可以引用它:

var CurrentDate = CommonClass.GetLocatDateTime(_userId);

那可能會返回一個DateTime

然后,如果CurrentDate == null,則使用UserId從該用戶的數據庫中獲取TimeZoneId-因此,數據庫調用只會發生一次,並且只有在之前從未發生過時才會發生。

但是,靜態類何時會“出生”並“被殺死”?

是用戶的每次會話嗎? 還是在Asp.Net應用程序運行時? 當我說用戶會話時,我的意思是,每次用戶單擊某項時,都會創建一個新會話,因此,將創建我的靜態類嗎? 還是靜態類對所有其他會話“可見”? 我希望它僅限於當前用戶。

但是,靜態類何時會“出生”並“被殺死”?

您不需要引用該類即可訪問靜態成員。 因此,永遠不會有生與死。

是用戶的每次會話嗎?

不,它對於整個應用程序是全局的,並且在所有用戶之間共享。

我希望它僅限於當前用戶。

然后忘記靜態成員並使用該會話。

靜態類成員在用戶會話之間共享。 但是,我看不到任何靜態方法的問題。 只要您不存儲共享(靜態)狀態(=您不使用靜態字段/屬性),就可以保證安全。

靜態等效於單例-在整個應用程序中是所有用戶通用的。 您需要基於會話的方法來實現此目的。 但是,如果您無權訪問會話(例如在業務庫中),則可以使用單例方法(以下代碼示例)。

編輯:使用單例方法(類似於靜態但更易於維護)實現此目的的代碼示例。 它使用EF代碼優先方法,因此,如果不使用EF,則應該對其進行調整:

編輯2:這是您應如何使用它:

要獲取用戶時區的時間:

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);`

如果添加了新用戶或修改了現有用戶,則可以重新加載時區:(可以根據需要對其進行進一步優化。)

UserDateTime.Instance.LoadTimezones();

實現方式:

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; }
    }
}

編輯:派生自ASP安全工具包

根據我的經驗,它是這樣的。

  • 用戶訪問該網站。
  • 網站啟動
  • 如果調用了靜態類,則將調用其靜態構造函數,並且該靜態類將“出生”
  • 用戶結束會話
  • 該應用程序和靜態類保持良好狀態
  • 另一個用戶訪問該網站並訪問靜態類
    • 靜態類的構造函數未調用,因為靜態類已經“出生”並且訪問其任何靜態變量都將與以前的用戶離開它們的方式相同
  • 沒有其他人會超過超時時間(通常在iis上將其設置為大約10分鍾)
  • 網站關閉並且處置了靜態類,下一個用戶將重新開始

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM