ASP.NET MVC如何避免静态变量?

ASP.NET MVC如何避免静态变量?,asp.net,asp.net-mvc,thread-safety,Asp.net,Asp.net Mvc,Thread Safety,最近发布了一篇关于质疑静态变量有多不安全的帖子,我发现我需要去掉它们。但我不知道该怎么做?我们考虑为每个类使用一个静态Get()方法,该方法返回一个实例,但该实例必须声明为静态 所以,唯一的方法是让实例引用(对于每个helper,即user helper.cs、imagehelper.cs等)声明为某种全局可访问类的实例属性?但是哪一类呢?这里有我遗漏的东西吗 下面是我需要更改的示例类的代码: sing System; using System.Collections.Generic; usin

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

所以,唯一的方法是让实例引用(对于每个helper,即user 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()
                {

                }
        }
}
sing系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用Mvc.Mailer;
命名空间MVCWebsite.Helpers
{
公共类应用程序设置
{
公共静态void OnAppInit()
{
//一般的
AppName=“MyApp”;
DesktopBaseURLs=新字典();
添加(“dev”,“localhost:50560”);
添加(“test”,“www.test.whatever.com”);
添加(“live”,“www.whatever.com”);
MobileBaseURLs=新字典();
添加(“dev”,“m.local.whatever.com”);
添加(“test”,“m.test.whatever.com”);
MobileBaseURLs.Add(“live”,“m.whatever.com”);
//电子邮件
EmailHostName=AppName+“.com”;//至少暂时
NoReplyEmailAddress=“无回复@”+EmailHostName.ToLower();
SupportEmailAddress=“support@”+EmailHostName.ToLower();
ErrorEmailAddress=“errors@”+EmailHostName.ToLower();
//资源
TempFileURL=“/content/temp/”;
UserDataURL=“/content/user content/”;
ProfilePicturesURL=UserDataURL+“profile pictures/”;
var a=GlobalHelper.geturlaserverpath(ProfilePicturesURL);
var b=a;
}
//一般的
公共静态字符串AppName{get;set;}
公共静态字典desktopbaseurl;
公共静态字典MobileBaseURLs;
//电子邮件
公共静态字符串EmailHostName{get;set;}
公共静态字符串NoReplyEmailAddress{get;set;}
公共静态字符串SupportEmailAddress{get;set;}
公共静态字符串ErrorEmailAddress{get;set;}
//资源
公共静态字符串UserDataURL{get;set;}
公共静态字符串TempFileURL{get;set;}
公共静态字符串配置文件PictureSURL{get;set;}
//方法
公共静态void SetAppURL()
{
}
}
}

前面问题的答案明确指出,IDictionary是静态方法中唯一不安全的变量,因为它不是线程安全的。您只需要以不同的方式存储这些变量。您不需要去掉所有的静态变量。您只需要将IDictionary更改为线程安全的


顺便说一句,那里有人对web.config做了很好的介绍。我建议为AppSettings类创建一个接口,以便您现在可以在控制器中使用它,并以您认为合适的不同方式实现它:

public interface IAppSettings
{
    string AppName { get; set; }
    ...
}
然后,您可以通过包装器类使用静态类立即实现它:

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

    ...
}

稍后,您可以创建一个使用会话、cookie或数据库值等的IAppSettings实现。重要的是要抽象出存储内容的方式,以便以满足需要的方式实现。

对,我想我已经弄明白了,它们应该作为实例变量存储在Global.asax.cs中。此文件包含从System.Web.HttpApplication继承的应用程序类。此主类仅限于每个请求一个实例(自身)。因此,如果您在此处存储对助手的任何引用,您可以通过调用mvcapapplication.MyHelper.DoSomething()来引用它们;有人请纠正我,如果这是错误的,但似乎对我来说是正确的。“在任何一个时间点,HTTPApplication实例只处理一个请求,因此我们不需要考虑锁定和解锁任何非静态成员,但对于静态成员,我们确实需要。”-从:

您没有将这些存储在Web.CONFIG中的任何原因?为什么您认为需要静态变量?考虑使用IOC框架。将值存储在Web.CONFIG中,然后使用IOC框架注入这些值是一个很好的解决方案。嗯,我来看看杰夫,谢谢。我想我需要静态的,因为我喜欢通过编程动态地创建全局引用。