C# ASP.Net中静态类的生命周期
在我的UI层中,我在会话状态中存储一些时区信息 我现在需要访问我的服务/业务/数据层中的时区 从我的UI层,我传递登录用户的用户ID,我的数据库为该用户存储了时区信息。我不想用用户ID传递时区 时区仅用于少数时间很重要的通话。(项目已经启动,今天有人休假等) 我想可能有一个静态类,它在所有层(服务/业务/数据)上都被引用,它有一个时区信息字段。我希望它是静态的,以便我可以引用它:C# ASP.Net中静态类的生命周期,c#,asp.net,session,C#,Asp.net,Session,在我的UI层中,我在会话状态中存储一些时区信息 我现在需要访问我的服务/业务/数据层中的时区 从我的UI层,我传递登录用户的用户ID,我的数据库为该用户存储了时区信息。我不想用用户ID传递时区 时区仅用于少数时间很重要的通话。(项目已经启动,今天有人休假等) 我想可能有一个静态类,它在所有层(服务/业务/数据)上都被引用,它有一个时区信息字段。我希望它是静态的,以便我可以引用它: var CurrentDate = CommonClass.GetLocatDateTime(_userId);
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);`
如果添加了新用户或修改了现有用户,您可以重新加载时区:(您可以根据需要进一步优化它。)
实施:
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; }
}
}
namespace-YourApp
{
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.Data.Entity;
类UserDateTime
{
public static readonly UserDateTime实例=new UserDateTime();
私有UserDateTime()//单例
{
加载时区();
}
私有字典_userTimezones=新字典();
公共日期时间获取时间(int userId)
{
if(_userTimezones.ContainsKey(userId))
返回TimeZoneInfo.ConvertTime(DateTime.UtcNow,TimeZoneInfo.FindSystemTimeZoneById(_userTimezones[userId]);
其他的
return DateTime.Now;//您可能会抛出一个错误。
}
公共时区()
{
使用(var db=new YourDbContext())
{
_userTimezones=db.userTimezones.ToDictionary(t=>t.UserId,t=>t.TimezoneId);
}
}
}
类用户时区
{
public int UserId{get;set;}
公共字符串TimezoneId{get;set;}
}
类YourDbContext:DbContext
{
公共数据库集用户时区{get;set;}
}
}
编辑:源于 Static相当于singleton–对整个应用程序通用,因此对所有用户都通用。您需要基于会话的方法来实现这一点。 但是,如果您不能访问会话(例如在业务库中),则可以使用单例方法(下面的代码示例) 编辑:使用单例方法实现这一点的代码示例(类似于静态方法,但更易于维护)。它使用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);`
如果添加了新用户或修改了现有用户,您可以重新加载时区:(您可以根据需要进一步优化它。)
实施:
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; }
}
}
namespace-YourApp
{
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.Data.Entity;
类UserDateTime
{
public static readonly UserDateTime实例=new UserDateTime();
私有UserDateTime()//单例
{
加载时区();
}
私有字典_userTimezones=新字典();
公共日期时间获取时间(int userId)
{
if(_userTimezones.ContainsKey(userId))
返回TimeZoneInfo.ConvertTime(DateTime.UtcNow,TimeZoneInfo.FindSystemTimeZoneById(_userTimezones[userId]);