具有非静态成员的静态类 ASP.NET MVC 应用程序的实例之间共享?



我有一个包含多个项目的解决方案,包括一个 ASP.NET MVC项目和一个WPF应用程序。在数据库中,我有一些常规设置,我想在两个应用程序中使用。为此,我创建了一个类库Foo,它将设置加载到字典中,并提供一种用于访问字典外特定设置的Get(string key)方法。 由于用户可以覆盖这些设置,因此我添加了一个包含 UserId 的属性。Get()方法会自动检查和使用UserId属性。这样,我就不需要在每次调用Get()方法时将 UserId 作为参数传递。

对于 WPF 应用程序,这工作得很好,因为只有一个实例在运行。但是对于Web项目,我希望仅填写一次字典(Application_Start()),并且所有访问该网站的用户都可以访问。如果我使类实例成为静态实例,这工作正常。但是,这不允许我有不同的UserIds,因为这将被访问该站点的每个用户的每个人覆盖。解决这个问题的最佳方法是什么?

这是我到目前为止尝试的(非常简化):

类库:

public class Foo ()
{
private Dictionary<string, string> Res;
private int UserId;
public Foo ()
{
Res = DoSomeMagicAndGetMyDbValues();
}
public void SetUser (int userId)
{
UserId = userId;
}
public string Get(string key)
{
var res = Res[key];
// do some magic stuff with the UserId
return res;
}
}

Global.asax:

public static Foo MyFoo;
protected void Application_Start()
{
MyFoo = new Foo();
}

用户控制器.cs:

public ActionResult Login(int userId)
{
MvcApplication.MyFoo.SetUser(userId); // <-- this sets the same UserId for all instances
}

将设置存储在Dictionary<int<Dictionary<string, string>>中,其中外部字典的KeyUserId,并保存默认设置的键0怎么样?当然,这意味着您必须将用户 ID 传递给 Get 和 Set 方法...

然后,您可以执行以下操作:

public static class Foo
{
private static Dictionary<int, Dictionary<string, string>> settings;
/// <summary>
/// Populates settings[0] with the default settings for the application
/// </summary>
public static void LoadDefaultSettings()
{
if (!settings.ContainsKey(0))
{
settings.Add(0, new Dictionary<string, string>());
}
// Some magic that loads the default settings into settings[0]
settings[0] = GetDefaultSettings();
}
/// <summary>
/// Adds a user-defined key or overrides a default key value with a User-specified value
/// </summary>
/// <param name="key">The key to add or override</param>
/// <param name="value">The key's value</param>
public static void Set(string key, string value, int userId)
{
if (!settings.ContainsKey(userId))
{
settings.Add(userId, new Dictionary<string, string>());
}
settings[userId][key] = value;
}
/// <summary>
/// Gets the User-defined value for the specified key if it exists, 
/// otherwise the default value is returned.
/// </summary>
/// <param name="key">The key to search for</param>
/// <returns>The value of specified key, or empty string if it doens't exist</returns>
public static string Get(string key, int userId)
{
if (settings.ContainsKey(userId) && settings[userId].ContainsKey(key))
{
return settings[userId][key];
}
return settings[0].ContainsKey(key) ? settings[0][key] : string.Empty;
}        
}

最新更新