C#类库 - 单例设计模式

时间:2011-12-12 14:59:54

标签: c# design-patterns singleton

背景/问题:

我对单身设计模式相当新鲜。我在Web应用程序中使用过一次(在SO社区的帮助下):

public static AppGlobal Instance
{
    get
    {
        if (HttpContext.Current.Session != null)
        {
            HttpSessionState session = HttpContext.Current.Session;

            if (session["AppGlobalInstance"] == null)
            {
                session["AppGlobalInstance"] = new AppGlobal();
            }

            return (AppGlobal)session["AppGlobalInstance"];
        }
        else
        {
            return null;
        }
    }
}

以上实现对我有意义,因为AppGlobal的实例存储在会话中。当会话终止时,AppGlobal就会死亡。如果我在Web应用程序调用的类库中使用相同的设计模式,会发生什么?例如,用户请求调用DLL中不知道会话的方法的页面。存储在单例实例中的数据是否会通过多次调用保留?

private static readonly Singleton instance = new Singleton();
private Singleton() { }

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

其他信息:

这就是我想要实现的目标:我有一个Web应用程序将从第三方应用程序接收XML请求。此XML将告诉我的Web应用程序执行以下三种操作之一(或全部三种操作)。我想有一个类的单例实例,用于存储可由多个类访问的数据。我希望每个请求后单例实例 DIE 。如果上述方法没有达到目的,那么实现它的最佳方法是什么?

注意:此Web应用程序在单个服务器上运行,并且从不在服务器场上运行。

编辑1:

根据以下建议,我使用System.Web.HttpContext.Current.Session来存储我的类实例。对于每个会话都是唯一的单例,这看起来是否正确(请记住我在类库中)?

    public static Ariba Instance
    {
        get
        {
            if (HttpContext.Current.Session != null)
            {
                HttpSessionState session = HttpContext.Current.Session;

                if (session["AribaInstance"] == null)
                {
                    session["AribaInstance"] = new Ariba();
                }

                return (Ariba)session["AribaInstance"];
            }
            else
            {
                return null;
            }
        }
    }

3 个答案:

答案 0 :(得分:4)

它将通过多次调用持久存在,但有一点需要注意。静态变量的范围限定为AppDomain,因此每当IIS工作进程被回收时,存储在静态变量中的任何数据都将丢失。会话数据也是如此,如果你将它“存储在proc中”。

如果您想要一个仅在HTTP请求期间存在的对象,则可以使用HttpContext.Items属性。

答案 1 :(得分:0)

由于单例是静态的,因此您的数据将可用于Web应用程序中的所有请求,因此它不会仅用于会话。

但是在ASP.NET应用程序中,您应该避免使用Singletons。相反,您应该使用Application对象。主要原因是,如果您将使用Web场,那么您的单例不再是应用程序范围的singelton,而只是在计算机上。

答案 2 :(得分:0)

哦! 如果要使用实例PER REQUEST,为什么不将它作为参数传递给要调用的方法,或者作为需要xml的类的构造函数参数。我认为这将是最好的设计方法。