Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#类库-单例设计模式_C#_Design Patterns_Singleton - Fatal编程技术网

C#类库-单例设计模式

C#类库-单例设计模式,c#,design-patterns,singleton,C#,Design Patterns,Singleton,背景/问题: 我对单例设计模式相当陌生。我曾经在web应用程序中使用过它(在SO社区的帮助下): 上面的实现对我来说很有意义,因为AppGlobal的实例存储在会话中。当会话终止时,AppGlobal终止。如果在web应用程序调用的类库中使用相同的设计模式,会发生什么情况?例如,用户请求一个调用DLL中不知道会话的方法的页面。存储在singleton实例中的数据是否会通过多次调用持久化 private static readonly Singleton instance = new Single

背景/问题:

我对单例设计模式相当陌生。我曾经在web应用程序中使用过它(在SO社区的帮助下):

上面的实现对我来说很有意义,因为
AppGlobal
的实例存储在会话中。当会话终止时,
AppGlobal
终止。如果在web应用程序调用的类库中使用相同的设计模式,会发生什么情况?例如,用户请求一个调用DLL中不知道会话的方法的页面。存储在singleton实例中的数据是否会通过多次调用持久化

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

public static Singleton Instance
{
    get
    {
        return instance;
    }
}
其他信息:

以下是我试图实现的目标:我有一个web应用程序,它将接收来自第三方应用程序的XML请求。这个XML将告诉我的web应用程序做三件事中的一件(或全部三件)。我希望有一个类的单例实例,它存储可由多个类访问的数据。我希望singleton实例在每次请求后都死亡。如果以上都不能做到这一点,那么最好的方法是什么

注意:此web应用程序在单个服务器上运行,并且永远不会在服务器场上运行

编辑1:

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


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

但是在ASP.NET应用程序中,应该避免使用单例。相反,您应该使用应用程序对象。主要原因是,如果您将使用web场,那么您的singleton就不再是应用范围内的singleton,而只是在机器上。

哦!
如果希望每个请求使用实例,为什么不将其作为参数传递给正在调用的方法,或者作为需要xml的类的构造函数参数传递呢。我认为这将是最好的设计方法。

它将通过多次调用保持,但有一个警告。静态变量的作用域是AppDomain,因此每当回收IIS工作进程时,静态变量中存储的任何数据都将丢失。如果您将会话数据存储在“proc”中,则会话数据也是如此


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

我已经考虑过这个问题,但我不想在我创建的每个方法的签名中添加8个参数。在这种情况下,是时候开始考虑使用依赖项注入了。大多数DI框架允许您使用“每个web请求”的生活方式配置对象,并将其注入依赖于它的类型中。这样就不必将它传递给调用堆栈中的所有方法(称为方法注入)。假设您不想将它们添加到构造函数中。您可以拥有一个具有这8个依赖项的类,并且只在签名中传递该类。使用这种方法,很容易在上面运行单元测试。如果您想继续以一种“静态”方式获取它们,则需要将对象放入HttpContext.Current.Items集合:公共静态MyObject{get{return(MyObject)HttpContext.Current.Items[“MyObject”];}set{HttpContext.Current.Items.Add(“MyObject”,value);}HttpContext.Current.Items是仅存在于请求中的字典。您可能需要在应用程序的请求结束事件(即在global.asax文件中)上清除(可能处置其中的一些对象?)您认为在服务器场中使用应用程序状态是错误的,您是指会话状态吗?可伸缩性-应用程序状态不在为同一应用程序提供服务的多个服务器之间共享(如在Web场中),也不在为同一服务器上的同一应用程序提供服务的多个工作进程之间共享(如在Web花园中)。因此,您的应用程序不能在不同的服务器或进程之间依赖包含应用程序状态相同数据的应用程序状态。如果您的应用程序将运行在多处理器或多服务器环境中,请考虑使用一个更可扩展的选项,例如数据库,以便在应用程序中保持保真度。如果是这种情况,则不需要在会话中存储任何内容。相反,您可以将对象存储在HttpContext.Current.Items[“AribaInstance”]中。如果您确实使用HttpContext.Current,我会补充一点,因为HttpContext.Current不会在ASP.NET之外填充(会话也是如此)。如果单元测试对您很重要,您需要包装上下文和会话对象。@AndyWilson,感谢您的提醒,为了答案!
private static readonly Singleton instance = new Singleton();
private Singleton() { }

public static Singleton Instance
{
    get
    {
        return instance;
    }
}
    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;
            }
        }
    }