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

时间:2013-01-09 23:04:59

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

最近发布了关于如何不安全的静态变量的问题,我发现我需要摆脱它们。但我无法弄清楚如何?正在为每个类考虑一个静态的Get()方法,它返回一个实例,但那个实例必须被声明为static。

所以唯一的方法就是让实例引用(对于每个帮助程序,I.E用户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()
                {

                }
        }
}

3 个答案:

答案 0 :(得分:2)

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

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

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

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

    ...
}

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

答案 1 :(得分:1)

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

顺便说一下,那里有人对web.config做了很好的准备

答案 2 :(得分:-1)

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

相关问题