【问题标题】:Static class with non-static members shared across instances of ASP.NET MVC app?具有跨 ASP.NET MVC 应用程序实例共享的非静态成员的静态类?
【发布时间】:2023-03-08 12:37:01
【问题描述】:

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

对于 WPF 应用程序,这工作得很好,因为只有一个实例正在运行。但是对于网络项目,我希望字典只填写一次(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;
    }
}

全球.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
}

【问题讨论】:

  • 请注意,model-view-controller 标签是针对有关模式的问题。 ASP.NET-MVC 实现有一个特定的标记。

标签: c# asp.net-mvc static


【解决方案1】:

如何将设置存储在Dictionary&lt;int&lt;Dictionary&lt;string, string&gt;&gt; 中,其中外部字典的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;
    }        
}

【讨论】:

  • 我想过实际上是这样尝试的。它工作正常。只是我很懒,不想为 Get() 上的每个调用传递用户 ID,这就是为什么我想知道是否有更好/其他方法来解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-04
  • 2012-04-13
  • 2013-06-20
  • 2011-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多