C# 单例和HttpApplicationState

C# 单例和HttpApplicationState,c#,.net,asp.net,singleton,C#,.net,Asp.net,Singleton,在web应用程序中,我只需要一个名为ProcessManager的类的实例。一种方法是让它成为单身汉。另一种方法是使用HttpApplicationState确保始终访问同一实例,如下所示: public static ProcessManager ProcessManager { get { HttpApplicationState applicationState = HttpContext.C

在web应用程序中,我只需要一个名为ProcessManager的类的实例。一种方法是让它成为单身汉。另一种方法是使用HttpApplicationState确保始终访问同一实例,如下所示:

public static ProcessManager ProcessManager
        {
            get 
            {
                HttpApplicationState applicationState = HttpContext.Current.Application;
                if (applicationState["ProcessManager"] == null)
                {
                    applicationState["ProcessManager"] = new ProcessManager();
                }

                return (ProcessManager)applicationState["ProcessManager"];
            }
        } 

哪种方法更好?为什么?

基于您给出的有限描述,我会选择单例,因为这样它就不依赖于HttpContext.Current,并且可以在ASP.Net管道之外使用(例如,当您想要编写单元测试时)

(顺便说一句,当您将某个内容设置为ApplicationState时,还需要首先调用它,然后在完成写入后解锁(),以确保它是线程安全的。)

或者,在创建ProcessManager时允许注入HttpContext,以便可以将其与模拟的HttpContext一起使用。

(我假设您的ProcessManager构造函数是私有的。)

让它成为一个真正的单例将是最好的,因为这种方法将使维护您的代码的其他程序员在结构上不可能意外地创建多个实例。没有什么可以阻止使用者直接访问HttpApplicationState并删除和替换ProcessManager实例。因此,您必须依靠约定来保护HttpApplicationState中的ProcessManager实例


只有当存在类的多个实例的实际用例时,才有意义允许多个实例化,同时依靠约定保护HttpApplicationState中的实例。

如果您计划将其实现为单例(也称为C#guru),他个人更喜欢下面的代码

public sealed class Singleton
{
    static readonly Singleton instance=new Singleton();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}

这篇文章是2006年写的。自2010年和.NET4以来,我们为使用LAZY的singleton提供了一个简单的构造: