【问题标题】:ASP.NET MVC How to avoid static variables?ASP.NET MVC 如何避免静态变量?
【发布时间】:2013-01-09 23:04:58
【问题描述】:

最近发布了关于质疑静态变量有多不安全的帖子,我发现我需要摆脱它们。但我不知道怎么做?正在为每个类考虑一个静态 Get() 方法,该方法返回一个实例,但该实例必须声明为静态。

因此,唯一的方法是让实例引用(对于每个帮助器、IE 用户 helper.cs、imagehelper.cs 等)将它们声明为某种全局可访问类的实例属性?但是哪个班?我这里有什么遗漏吗?

下面我需要更改的示例类的代码:

sing System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Mvc.Mailer;

namespace MVCWebsite.Helpers
{
        public class AppSettings
        {
                public static void OnAppInit()
                {
                        //General
                        AppName = "MyApp";
                        DesktopBaseURLs = new Dictionary<string, string>();
                        DesktopBaseURLs.Add("dev", "localhost:50560");
                        DesktopBaseURLs.Add("test", "www.test.whatever.com");
                        DesktopBaseURLs.Add("live", "www.whatever.com");
                        MobileBaseURLs = new Dictionary<string, string>();
                        MobileBaseURLs.Add("dev", "m.local.whatever.com");
                        MobileBaseURLs.Add("test", "m.test.whatever.com");
                        MobileBaseURLs.Add("live", "m.whatever.com");

                        //Emails
                        EmailHostName = AppName + ".com"; //For the moment atleast
                        NoReplyEmailAddress = "no-reply@" + EmailHostName.ToLower();
                        SupportEmailAddress = "support@" + EmailHostName.ToLower();
                        ErrorEmailAddress = "errors@" + EmailHostName.ToLower();

                        //Resources
                        TempFileURL = "/content/temp/";
                        UserDataURL = "/content/user-content/";
                        ProfilePicturesURL = UserDataURL + "profile-pictures/";

                        var a = GlobalHelper.GetURLAsServerPath(ProfilePicturesURL);
                        var b = a;

                }

                //General
                public static string AppName { get; set; }
                public static Dictionary<string, string> DesktopBaseURLs;
                public static Dictionary<string, string> MobileBaseURLs;

                //Emails
                public static string EmailHostName { get; set; }
                public static string NoReplyEmailAddress { get; set; }
                public static string SupportEmailAddress { get; set; }
                public static string ErrorEmailAddress { get; set; }

                //Resources
                public static string UserDataURL { get; set; }
                public static string TempFileURL { get; set; }
                public static string ProfilePicturesURL { get; set; }

                //Methods
                public static void SetAppURL()
                {

                }
        }
}

【问题讨论】:

  • 有什么理由不将这些存储在 web.config 中?
  • 为什么你认为你需要静态变量?
  • 考虑使用 IoC 框架。
  • 将值存储在 web.config 中,然后使用 IoC 框架注入这些值是一个很好的解决方案。
  • 嗯,我会调查那个 Jeff,谢谢。我想我需要静态的,因为我喜欢以编程方式动态创建全局引用。

标签: asp.net asp.net-mvc thread-safety


【解决方案1】:

我建议为您的 AppSettings 类创建一个接口,以便您现在可以在控制器中使用它,并以您认为合适的不同方式实现它:

public interface IAppSettings
{
    string AppName { get; set; }
    ...
}

然后您可以通过包装类使用静态类立即实现它:

public class AppSettingsWrapper : IAppSettings
{
    public AppName
    {
        get
        {
            return AppSettings.AppName;
        }
        set
        {
            AppSettings.AppName = value;
        }
    }

    ...
}

稍后,您可以创建使用会话、cookie、数据库值或其他任何内容的 IAppSettings 实现。重要的是抽象您存储事物的方式,以便您可以以满足您需求的方式实现。

【讨论】:

    【解决方案2】:

    对您上一个问题的回答清楚地表明 IDictionary 是您的静态方法中唯一不安全的变量,因为它不是线程安全的。您只需要以不同的方式存储这些变量。您不需要摆脱所有静态变量。您只需要将 IDictionary 更改为线程安全的。

    顺便说一句,那里有人对 web.config 发表了很好的评论

    【讨论】:

      【解决方案3】:

      是的,我想我已经弄清楚了,它们应该作为实例变量存储在 Global.asax.cs 中。该文件包含继承自 System.Web.HttpApplication 的 Application 类。这个主类被限制为每个请求一个(本身的)实例。因此,如果您在此处存储对助手的任何引用,则可以通过 MvcApplication.MyHelper.DoSomething(); 来引用它们。如果这是错误的,请有人纠正我,但对我来说似乎是正确的。 “在任何一个时间点,一个 HTTPApplication 实例只处理一个请求,所以我们不需要考虑任何非静态成员的锁定和解锁,但对于静态成员,我们确实需要。” -来自:http://www.codeproject.com/Articles/87316/A-walkthrough-to-Application-State#c

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-19
        • 2013-04-07
        • 2011-04-03
        • 1970-01-01
        • 1970-01-01
        • 2014-12-19
        • 1970-01-01
        相关资源
        最近更新 更多